[
  {
    "path": ".agents/architecture.md",
    "content": "# Nitro Architecture Deep Dive\n\n## Core Instance (`src/nitro.ts`)\n\n`createNitro(config, opts)` creates the main context with:\n- `options: NitroOptions` — Resolved configuration\n- `hooks: Hookable<NitroHooks>` — Build lifecycle hooks\n- `vfs: Map<string, { render }>` — Virtual file system\n- `routing: { routes, routeRules, globalMiddleware, routedMiddleware }`\n- `scannedHandlers: NitroEventHandler[]`\n- `unimport?: Unimport` — Auto-imports (optional)\n- `logger: ConsolaInstance`\n- `updateConfig(config)` — Hot-reload config\n- `close()` — Cleanup\n\n**Setup flow:**\n1. Load options via `loadOptions()`\n2. Install modules via `installModules()`\n3. Init routing via `initNitroRouting()`\n4. Scan handlers/plugins/tasks via `scanAndSyncOptions()`\n5. Prepare unimport for auto-imports\n6. Setup hooks\n\n## Entry Points\n\n- `src/builder.ts` — Main public API: `createNitro()`, `build()`, `createDevServer()`, `prerender()`, `copyPublicAssets()`, `prepare()`, `writeTypes()`, `runTask()`, `listTasks()`\n- `src/vite.ts` — Vite plugin export from `src/build/vite/plugin.ts`\n\n## Build System (`src/build/`)\n\n**Builder dispatch** (`build/build.ts`): delegates to `rollup`, `rolldown`, or `vite` based on `nitro.options.builder`.\n\n**Builder selection** (resolved in `config/resolvers/builder.ts`):\n- Check `NITRO_BUILDER` / `NITRO_VITE_BUILDER` env vars\n- Auto-detect available packages\n- Fallback: rolldown → vite → rollup\n\n**Base config** (`build/config.ts`):\n- Extensions: `.ts`, `.mjs`, `.js`, `.json`, `.node`, `.tsx`, `.jsx`\n- Import.meta replacements (`import.meta.dev`, `import.meta.preset`, etc.)\n- Unenv aliases for polyfills\n- External dependency patterns\n\n**Plugins** (`build/plugins.ts`):\n1. Virtual modules — renders from `build/virtual/`\n2. Auto imports — Unimport plugin\n3. WASM loader — unwasm\n4. Server main injection — `globalThis.__server_main__`\n5. Raw imports — `?raw` suffix\n6. Route meta — OpenAPI metadata\n7. Replace plugin — variable substitution\n8. Externals plugin — Node.js native resolution\n9. Sourcemap minify (optional)\n\n**Virtual modules** (`build/virtual/`, 14 templates):\nAll prefixed `#nitro/virtual/<name>`:\n- `routing.ts` — Compiled router matcher\n- `plugins.ts` — Plugin registry\n- `error-handler.ts` — Error handler\n- `public-assets.ts` — Public asset metadata\n- `server-assets.ts` — Server asset metadata\n- `runtime-config.ts` — Runtime config object\n- `database.ts` — Database setup\n- `storage.ts` — Storage backends\n- `tasks.ts` — Task registry\n- `polyfills.ts` — Env polyfills\n- `feature-flags.ts` — Feature detection\n- `routing-meta.ts` — Route metadata (OpenAPI)\n- `renderer-template.ts` — SSR renderer\n- `_all.ts` — Aggregator\n\n## Configuration System (`src/config/`)\n\n**Loader** (`config/loader.ts`): `loadOptions(config, opts)`\n1. Merge with defaults (`NitroDefaults`)\n2. Load c12 config files (`nitro.config.ts`, `package.json.nitro`, etc.)\n3. Resolve preset\n4. Run config resolvers sequentially\n\n**Resolvers** (`config/resolvers/`):\n`compatibility`, `tsconfig`, `paths`, `imports`, `route-rules`, `database`, `export-conditions`, `runtime-config`, `open-api`, `url`, `assets`, `storage`, `error`, `unenv`, `builder`\n\n**Defaults** (`config/defaults.ts`): All NitroConfig defaults.\n\n## Runtime (`src/runtime/`)\n\n**Internal** (`runtime/internal/`):\n- `app.ts` — NitroApp creation, H3 app setup\n- `cache.ts` — Response caching\n- `context.ts` — Async context\n- `route-rules.ts` — Route rule middleware (headers, redirect, proxy, cache, cors)\n- `static.ts` — Static file serving\n- `task.ts` — Task execution\n- `plugin.ts` — Plugin helpers\n- `runtime-config.ts` — Config getter\n\n**Public exports**: `runtime/app.ts` (`defineConfig()`), `runtime/nitro.ts` (`serverFetch()`), `runtime/cache.ts`, `runtime/task.ts`, `runtime/storage.ts`, etc.\n\n## Dev Server (`src/dev/`)\n\n- `dev/server.ts` — `NitroDevServer`: Worker management via `env-runner`, restart on failure (max 3 retries), WebSocket support, VFS debug endpoint (`/_vfs/**`)\n- `dev/app.ts` — `NitroDevApp`: H3 app with error handling, static serving with compression, dev proxy\n\n## Prerender (`src/prerender/`)\n\n- `prerender/prerender.ts` — Main flow: parse routes → build prerenderer (preset: `nitro-prerender`) → execute in parallel → link crawling → write to disk → compress\n- `prerender/utils.ts` — `extractLinks()`, `matchesIgnorePattern()`, `formatPrerenderRoute()`\n\n## Routing & Scanning (`src/routing.ts`, `src/scan.ts`)\n\n**Scanning**: Discovers routes, middleware, plugins, tasks, modules from filesystem.\n\nRoute file conventions:\n- `routes/index.ts` → `GET /`\n- `routes/users/[id].ts` → `GET /users/:id`\n- `routes/users/[...slug].ts` → `GET /users/**:slug`\n- `api/users.post.ts` → `POST /api/users`\n- `.dev`/`.prod`/`.prerender` suffixes for environment filtering\n\n**Router** (`Router` class): Based on `rou3`, compiles to optimized string matcher, supports method routing + env conditions.\n\n## Presets (`src/presets/`)\n\n31 presets. Structure per preset:\n```\npresets/<name>/\n├── preset.ts        # defineNitroPreset()\n├── runtime/         # Runtime entry (bundled)\n├── types.ts         # Types (optional)\n├── utils.ts         # Build-time utils (optional)\n└── unenv/           # Env overrides (optional)\n```\n\nKey presets: `standard`, `node` (server/middleware/cluster), `cloudflare` (pages/workers), `vercel`, `netlify`, `aws-lambda`, `deno`, `firebase`, `azure`, `bun`, `winterjs`\n\nResolution: `presets/_resolve.ts` handles aliases, dev/prod, compat dates, static hosting.\n\n## CLI (`src/cli/`)\n\nUses `citty` with lazy-loaded commands: `dev`, `build`, `deploy`, `preview`, `prepare`, `task`, `docs`.\n\n## Key Libraries\n\n| Library | Purpose |\n|---------|---------|\n| `h3` | HTTP framework |\n| `rou3` | Route matching |\n| `c12` | Config loading |\n| `citty` | CLI framework |\n| `hookable` | Hook system |\n| `unimport` | Auto-imports |\n| `unstorage` | Storage abstraction |\n| `unenv` | Runtime polyfills |\n| `defu` | Config merging |\n| `pathe` | Path operations |\n| `consola` | Logging |\n| `env-runner` | Worker management |\n"
  },
  {
    "path": ".agents/docs.md",
    "content": "# Documentation Guide\n\n## Structure\n\nDocumentation lives in `docs/` and is built with [UnDocs](https://github.com/unjs/undocs).\n\n```\ndocs/\n  .docs/          # UnDocs Nuxt app (components, pages, layouts, utils)\n  .config/        # docs.yaml (site config), automd.config.ts\n  1.docs/         # Core documentation (getting started, routing, cache, etc.)\n  2.deploy/       # Deployment docs (runtimes, providers)\n  3.config/       # Config reference\n  4.examples/     # Examples index\n  index.md        # Homepage\n```\n\nNumeric prefixes control navigation order. Files with the same prefix are sorted alphabetically.\n\n## Conventions\n\n### Preset Names\n\nCanonical preset names use **underscores** (e.g., `node_server`, `cloudflare_module`, `digital_ocean`). Both underscores and hyphens are supported at runtime (resolved via `kebabCase`), but docs should use underscore form.\n\n### Import Paths\n\nNitro v3 uses subpath exports — not deep runtime imports:\n\n```ts\nimport { defineHandler, readBody, getQuery } from \"nitro/h3\";\nimport { defineCachedHandler, defineCachedFunction } from \"nitro/cache\";\nimport { useStorage } from \"nitro/storage\";\nimport { useDatabase } from \"nitro/database\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\nimport { defineNitroConfig } from \"nitro/config\";\nimport { definePlugin } from \"nitro\";        // runtime plugin\nimport { defineRouteMeta } from \"nitro\";      // route meta macro\n```\n\n### H3 v2 API\n\nNitro v3 uses H3 v2. Key differences from v1:\n\n- **Handler**: `defineHandler()` (not `eventHandler` / `defineEventHandler`)\n- **Error**: `throw new HTTPError(message, { status })` (not `createError()`)\n- **Router**: `new H3()` (not `createApp()` / `createRouter()`)\n- **Response**: Return values directly; no `send()` function\n- **Headers**: `event.res.headers.set(name, value)` (not `setResponseHeader(event, name, value)`)\n- **Hooks**: `request` hook receives `(event: HTTPEvent)`, not `(req)`\n\n### Code Examples\n\n- **Auto imports are not available** — always show explicit imports in examples\n- Always use `defineHandler` from `\"nitro/h3\"` (not `eventHandler`)\n- Always use `defineNitroConfig` from `\"nitro/config\"` (not `defineConfig`)\n- Include import statements in code examples\n- Use `\"nitro/*\"` imports, never `\"nitropack/*\"`\n\n### Node.js Version\n\nNitro v3 requires Node.js >= 20. All deployment docs should reference Node.js 20+ (not 16 or 18).\n\n### Environment Variables\n\nThe preset env var is `NITRO_PRESET` (not `SERVER_PRESET` or any other name).\n\n### Runtime Config\n\n- Prefix: `NITRO_` for env var overrides\n- camelCase in config, UPPER_SNAKE_CASE in env vars\n\n## Common Mistakes to Avoid\n\n- Using `send(event, value)` — removed in h3 v2, return values directly\n- Using `createError()` — use `new HTTPError()` or `HTTPError.status()`\n- Using `eventHandler()` — use `defineHandler()`\n- Using `defineConfig()` for nitro config — use `defineNitroConfig()`\n- Duplicate imports (e.g., importing `defineHandler` from both `nitro/h3` and `nitro/cache`)\n- Wrong env var names (e.g., `NITR_PRESET`, `SERVER_PRESET`)\n- Outdated Node.js versions in deployment examples\n- Using hyphen preset names in docs (use underscores)\n\n## MDC Syntax Reference\n\nDocs use [MDC](https://content.nuxt.com/) (Markdown Components) syntax to embed Vue components in markdown.\n\n### Block Components\n\nUse `::` for block components. Nesting increases the colon count:\n\n```markdown\n::component-name\nContent here\n::\n\n::component{prop=\"value\" boolProp}\nContent\n::\n```\n\nNested (each level adds one `:`):\n\n```markdown\n::parent\n  :::child\n  Content\n  :::\n::\n```\n\n### Props\n\n**Inline:** `::alert{type=\"warning\" icon=\"i-lucide-alert\"}`\n\n**YAML block** (for multiple props):\n\n```markdown\n::component\n---\ntitle: My Title\nicon: i-lucide-rocket\n---\nContent\n::\n```\n\n### Slots\n\nNamed slots use `#`:\n\n```markdown\n::hero\nDefault slot content\n\n#title\nTitle slot content\n\n#description\nDescription slot content\n\n#links\n  :::u-button{to=\"/docs\"}\n  Get Started\n  :::\n::\n```\n\n### Inline Components & Attributes\n\n```markdown\n:inline-component{prop=\"value\"}\n\nHello [World]{.text-primary style=\"color: green;\"}\n```\n\n### Variables\n\n```markdown\n---\ntitle: My Page\n---\n# {{ $doc.title }}\n```\n\n## Prose Components (Typography)\n\nThese are available in markdown files for documentation content. Provided by [Nuxt UI](https://ui.nuxt.com/).\n\n### Callouts\n\n```markdown\n::note\nAdditional information for the user.\n::\n\n::tip\nHelpful suggestion or best practice.\n::\n\n::warning\nCaution about potential unexpected results.\n::\n\n::caution\nWarning about irreversible or dangerous actions.\n::\n```\n\nGeneric callout with props:\n\n```markdown\n::callout{icon=\"i-lucide-info\" color=\"primary\"}\nCustom callout content with **markdown**.\n::\n```\n\nColors: `primary`, `secondary`, `success`, `info`, `warning`, `error`, `neutral`.\n\n### Tabs\n\n```markdown\n::tabs\n  :::tabs-item{label=\"npm\" icon=\"i-lucide-package\"}\n  ```bash\n  npm install nitro\n  ```\n  :::\n  :::tabs-item{label=\"pnpm\"}\n  ```bash\n  pnpm add nitro\n  ```\n  :::\n::\n```\n\nProps: `orientation` (`horizontal`|`vertical`), `defaultValue`, `content`, `unmountOnHide`.\n\n### Steps\n\n```markdown\n::steps{level=\"3\"}\n### Install\nInstall the package.\n\n### Configure\nAdd to your config.\n\n### Deploy\nDeploy your app.\n::\n```\n\n`level` prop: `\"2\"`, `\"3\"` (default), `\"4\"` — determines which heading level becomes numbered steps.\n\n### Code Group\n\n```markdown\n::code-group\n```ts [nuxt.config.ts]\nexport default defineNuxtConfig({})\n```\n```ts [nitro.config.ts]\nexport default defineNitroConfig({})\n```\n::\n```\n\nProps: `defaultValue`, `sync` (persists selection to localStorage).\n\n### Code Tree\n\nInteractive file tree with code preview:\n\n```markdown\n::code-tree{defaultValue=\"routes/hello.ts\" expand-all}\n  ::prose-pre{filename=\"routes/hello.ts\"}\n  ```ts\n  export default defineHandler(() => 'Hello!')\n  ```\n  ::\n  ::prose-pre{filename=\"vite.config.ts\"}\n  ```ts\n  import { nitro } from 'nitro/vite'\n  export default defineConfig({ plugins: [nitro()] })\n  ```\n  ::\n::\n```\n\nProps: `defaultValue`, `expandAll`, `items`.\n\n### Card\n\n```markdown\n::card{title=\"Storage\" icon=\"i-lucide-database\" to=\"/docs/storage\"}\nAccess key-value storage in your handlers.\n::\n```\n\nProps: `title`, `icon`, `color`, `to`, `target`, `variant` (`solid`|`outline`|`soft`|`subtle`).\n\n### Field\n\nDocument API parameters:\n\n```markdown\n::field{name=\"preset\" type=\"string\" required}\nThe deployment preset to use.\n::\n```\n\nProps: `name`, `type`, `description`, `required`.\n\n### Collapsible\n\n```markdown\n::collapsible{name=\"Advanced Options\"}\nHidden content shown on expand.\n::\n```\n\nProps: `name`, `size`, `color`, `defaultOpen`, `unmountOnHide`.\n\n### Kbd (Keyboard)\n\n`:kbd[Ctrl]` + `:kbd[C]` renders keyboard shortcuts inline.\n\n### Icon\n\n`:icon{name=\"i-lucide-rocket\"}` renders an inline icon.\n\n### Prose Pre (Code Block)\n\nExplicit code block with filename:\n\n```markdown\n::prose-pre{filename=\"server.ts\"}\n```ts\nexport default { fetch: () => new Response('ok') }\n```\n::\n```\n\n## Landing Page Components\n\nThese are Nuxt UI `Page*` components used in `docs/index.md` for the homepage. Prefix with `u-` in MDC.\n\n### PageHero (`::u-page-hero`)\n\n```markdown\n::u-page-hero\n---\norientation: horizontal\n---\n#title\nShip [Full-Stack]{.text-primary} Vite Apps\n\n#description\nBuild production-ready server applications.\n\n#links\n  :::u-button{size=\"xl\" to=\"/docs\"}\n  Get Started\n  :::\n\n#default\n  :::some-illustration\n  :::\n::\n```\n\nProps: `title`, `description`, `headline`, `orientation` (`vertical`|`horizontal`), `reverse`, `links` (ButtonProps[]).\nSlots: `top`, `header`, `headline`, `title`, `description`, `body`, `footer`, `links`, `default`, `bottom`.\n\n### PageSection (`::u-page-section`)\n\n```markdown\n::u-page-section\n---\norientation: horizontal\nfeatures:\n  - title: Feature One\n    description: Description here\n    icon: i-lucide-zap\n---\n#title\nSection Title\n\n#description\nSection description text.\n::\n```\n\nProps: `headline`, `icon`, `title`, `description`, `orientation`, `reverse`, `links` (ButtonProps[]), `features` (PageFeatureProps[]).\nSlots: `top`, `header`, `leading`, `headline`, `title`, `description`, `body`, `features`, `footer`, `links`, `default`, `bottom`.\n\n### PageFeature (`::u-page-feature`)\n\n```markdown\n:::::u-page-feature\n#title\nFeature Name\n\n#description\nFeature description text.\n:::::\n```\n\nProps: `icon`, `title`, `description`, `orientation` (`horizontal`|`vertical`), `to`, `target`.\nSlots: `leading`, `title`, `description`, `default`.\n\n### PageGrid (`::u-page-grid`)\n\nResponsive grid (1→2→3 columns). Wraps `PageCard` or `PageFeature` children:\n\n```markdown\n::::u-page-grid\n  :::::u-page-card{title=\"Card\" icon=\"i-lucide-box\"}\n  Card content\n  :::::\n::::\n```\n\n### PageCard (`::u-page-card`)\n\n```markdown\n::u-page-card{title=\"Title\" icon=\"i-lucide-box\" to=\"/link\"}\nCard body content.\n::\n```\n\nProps: `icon`, `title`, `description`, `orientation`, `reverse`, `highlight`, `highlightColor`, `spotlight`, `spotlightColor`, `variant`, `to`, `target`.\nSlots: `header`, `leading`, `title`, `description`, `body`, `footer`, `default`.\n\n### PageCTA (`::u-page-cta`)\n\nCall-to-action block:\n\n```markdown\n::u-page-cta\n---\nvariant: solid\nlinks:\n  - label: Get Started\n    to: /docs\n    color: neutral\n---\n#title\nReady to get started?\n\n#description\nDeploy your app in minutes.\n::\n```\n\nProps: `title`, `description`, `orientation`, `reverse`, `variant` (`outline`|`solid`|`soft`|`subtle`|`naked`), `links`.\n\n### PageLogos (`::u-page-logos`)\n\n```markdown\n::u-page-logos\n---\ntitle: Trusted by\nmarquee: true\nitems:\n  - i-simple-icons-github\n  - i-simple-icons-vercel\n---\n::\n```\n\nProps: `title`, `items` (icon strings or `{src, alt}` objects), `marquee` (boolean or MarqueeProps).\n\n### PageLinks (`::u-page-links`)\n\n```markdown\n::u-page-links\n---\ntitle: Community\nlinks:\n  - label: GitHub\n    icon: i-simple-icons-github\n    to: https://github.com/nitrojs/nitro\n---\n::\n```\n\n### Other Page Components\n\n- **PageHeader** — Page title/description header\n- **PageBody** — Main content wrapper\n- **PageColumns** — Multi-column layout\n- **PageList** — Vertical list of items\n- **PageAnchors** — Anchor link navigation\n- **PageAside** — Sidebar content\n\n## Nuxt Content Querying (for custom components)\n\n```ts\n// Single page by path\nconst page = await queryCollection('docs').path('/hello').first()\n\n// Filtered list\nconst posts = await queryCollection('blog')\n  .where('draft', '=', false)\n  .order('date', 'DESC')\n  .all()\n\n// Navigation tree\nconst nav = await queryCollectionNavigation('docs')\n\n// Prev/next\nconst [prev, next] = await queryCollectionItemSurroundings('docs', '/current')\n```\n\n## Custom Components\n\nProject-specific components live in `docs/.docs/components/` and can be used in markdown with `:component-name` or `::component-name` syntax (e.g., `:page-sponsors`, `:hero-background` as seen in `index.md`).\n"
  },
  {
    "path": ".agents/presets.md",
    "content": "# Nitro Presets Reference\n\n## All Presets (31)\n\n### Core\n- `_nitro/` — Internal presets (dev, prerender, worker modes)\n- `standard/` — Framework-agnostic standard server\n- `node/` — Node.js (server, middleware, cluster)\n- `bun/` — Bun runtime\n\n### Cloud Providers\n- `aws-lambda/` — AWS Lambda\n- `aws-amplify/` — AWS Amplify\n- `azure/` — Azure Static Web Apps\n- `cloudflare/` — Cloudflare Pages/Workers\n- `deno/` — Deno Deploy\n- `firebase/` — Firebase Hosting\n- `netlify/` — Netlify Functions/Edge\n- `vercel/` — Vercel Functions/Edge\n- `digitalocean/` — DigitalOcean App Platform\n- `heroku/` — Heroku\n- `koyeb/` — Koyeb\n- `zeabur/` — Zeabur\n- `render.com/` — Render\n- `stormkit/` — Stormkit\n- `genezio/` — Genezio\n- `winterjs/` — WinterJS\n- `zephyr/` — Zephyr\n- `alwaysdata/`\n- `cleavr/`\n- `flightcontrol/`\n- `iis/`\n- `platform.sh/`\n\n## Preset Structure\n\n```\npresets/<name>/\n├── preset.ts        # defineNitroPreset() — config overrides, hooks\n├── runtime/         # Runtime entry points (bundled into output)\n│   └── <name>.ts    # Platform-specific request handler\n├── types.ts         # TypeScript types (optional)\n├── utils.ts         # Build-time utilities (optional)\n└── unenv/           # Environment polyfill overrides (optional)\n    ├── preset.ts\n    └── node-compat.ts\n```\n\n## Creating a Preset\n\nUse `defineNitroPreset()` from `src/presets/_utils/preset.ts`:\n\n```ts\nimport { defineNitroPreset } from \"../_utils/preset.ts\";\n\nexport default defineNitroPreset({\n  // Preset metadata\n  entry: \"./runtime/<name>.ts\",\n  // NitroConfig overrides\n  node: false,\n  // Hooks\n  hooks: {\n    \"build:before\": async (nitro) => { /* ... */ },\n  },\n});\n```\n\n## Preset Resolution (`presets/_resolve.ts`)\n\n`resolvePreset(name, opts)` considers:\n- Preset name aliases\n- Dev vs production mode\n- Compatibility dates\n- Static hosting detection\n- Generated mappings in `_all.gen.ts` and `_types.gen.ts`\n"
  },
  {
    "path": ".agents/skills/update-deps/SKILL.md",
    "content": "# Update Dependencies Skill\n\nThis skill guides you through the process of updating dependencies in the Nitro repository.\n\n## Step-by-Step Process\n\n### Ensure Clean State\n\nCheck that you're on a clean main branch with latest changes.\n\n- Clean working directory on main branch\n- Latest changes pulled from remote\n\n```bash\ngit checkout main\ngit pull origin main\ngit status  # Should show \"nothing to commit, working tree clean\"\n```\n\n(if branch name starts with chore, you can stay in it, no need to pull or change branch or clean state)\n\n### Initial Install\n\nRun an initial install to ensure everything is up to date:\n\n```bash\npnpm install\n```\n\n### Run pnpm upgrade -r\n\nRun `pnpm upgrade -r` to update non-major versions.\n\nAfter upgrade, check git diff:\n\n- Make sure range types does not change in `dependencies` field (example: `\"h3\": \"^2.0.1-rc.7\"` should remain `\"h3\": \"^2.0.1-rc.7\",` not `\"h3\": \"2.0.1-rc.7\",`)\n- Make sure dependencies are not converted to `link:..` (example: `\"nitro\": \"latest\",` should remain same, instead of `\"nitro\": \"link:../..\"`)\n\n**Fix workspace package link references:**\n\n`pnpm upgrade -r` often incorrectly converts workspace package references (like `\"nitro\": \"latest\"`) to link format (`\"nitro\": \"link:../..\"`) in monorepo packages.\n\nCheck git diff for any workspace packages that were converted to `link:` format:\n\n```bash\n# Check for any link: conversions in modified files\ngit diff --name-only | xargs grep -l '\"link:' 2>/dev/null\n```\n\nIf found, revert them back to their original format. For this repo, `\"nitro\"` should always be `\"latest\"`:\n\n```bash\n# Revert nitro link references back to latest in all modified package.json files\ngit diff --name-only | grep 'package.json$' | while read file; do\n  if grep -q '\"nitro\": \"link:' \"$file\" 2>/dev/null; then\n    sed -i 's/\"nitro\": \"link:[^\"]*\"/\"nitro\": \"latest\"/g' \"$file\"\n    echo \"Fixed: $file\"\n  fi\ndone\n```\n\n**Fix caret prefix removal:**\n\nIf any dependencies in root `package.json` lost their `^` prefix, restore them manually.\n\n### Check for Outdated Dependencies\n\nFind outdated dependencies:\n\n```bash\npnpm outdated -r\n```\n\n**IMPORTANT**: Check for newer beta/alpha/rc versions manually. `pnpm outdated` doesn't show pre-release updates.\n\nCheck each package with beta/alpha/rc versions in package.json:\n\n```bash\n# List all versions including pre-releases\npnpm show vite versions --json | grep -E \"beta|alpha|rc\" | tail -5\npnpm show youch versions --json | grep -E \"beta|alpha|rc\" | tail -5\n```\n\nOr check all versions for a specific package:\n\n```bash\npnpm show <package-name> versions\n```\n\n### 4. Update Dependencies\n\nManually update all dependencies to their latest versions in [package.json](../package.json):\n\n- Update both `dependencies` and `devDependencies`\n- Keep the range prefix (e.g., `^` for caret ranges)\n- **For beta/alpha/rc packages**: Update to the latest pre-release tag found in step 3\n  - Example: `vite: \"8.0.0-beta.6\"` → `\"8.0.0-beta.7\"`\n  - Example: `h3: \"^2.0.1-rc.7\"` → `\"^2.0.1-rc.8\"` (if available)\n- Maintain version range conventions (prefer `^` over exact versions)\n- **Do not update** `@azure/functions`\n\n### 5. Clean Install\n\nRemove lock file and node_modules, then reinstall:\n\n```bash\nrm -rf node_modules pnpm-lock.yaml\npnpm i\n```\n\n### 6. Lint and Fix\n\nRun linting and auto-fix issues:\n\n```bash\npnpm format\n```\n\n### 7. Build Project\n\nBuild the project to ensure compatibility:\n\n```bash\npnpm build\n```\n\n### 9. Fix Remaining Issues\n\nIf there are lint or type errors:\n\n1. Review the output carefully\n2. Fix issues manually following the project conventions\n3. Re-run `pnpm format` to verify lint fixes\n4. Re-run `pnpm typecheck` to verify type fixes. Ignore errors, only report them in the end.\n\n### 10. Final\n\nDo not commit changes. Only summarize what happened.\n\n## Common Issues\n\n### Breaking Changes\n\nIf a dependency has breaking changes:\n\n- Check the package's changelog/release notes\n- Update code to match new API if needed\n- Consider pinning to previous major version if breaking changes are too extensive\n\n### Build Failures\n\nIf the build fails after updates:\n\n- Check for TypeScript errors first: `pnpm typecheck`\n- Review error messages for deprecated APIs\n- Consider updating dependencies one at a time to isolate issues\n\n### Lock File Conflicts\n\n- Test thoroughly after updates, especially major version bumps\n- Review changelogs for significant updates\n"
  },
  {
    "path": ".agents/testing.md",
    "content": "# Nitro Testing Guide\n\n## Test Structure\n\n```\ntest/\n├── tests.ts            # Main test definitions (shared across presets)\n├── fixture/            # Test fixture Nitro app\n│   ├── nitro.config.ts\n│   ├── routes/         # Test route handlers\n│   ├── api/            # Test API handlers\n│   ├── middleware/      # Test middleware\n│   ├── plugins/        # Test plugins\n│   └── public/         # Test static assets\n├── presets/            # Per-preset test setup\n│   ├── node.test.ts\n│   ├── cloudflare.test.ts\n│   ├── vercel.test.ts\n│   └── ...\n├── unit/               # Isolated unit tests\n└── minimal/            # Minimal bundle output tests\n```\n\n## How Tests Work\n\n1. `test/tests.ts` defines shared test cases using vitest\n2. Each `test/presets/<name>.test.ts` imports shared tests and runs them against a specific preset\n3. The test fixture in `test/fixture/` is a full Nitro app used as the test target\n4. Preset tests build the fixture with the preset, then run HTTP assertions\n\n## Adding Regression Tests\n\n1. Add test route/handler to `test/fixture/` (e.g., `test/fixture/routes/new-feature.ts`)\n2. Add test case to `test/tests.ts`\n3. Run `pnpm vitest run test/presets/node.test.ts` to verify\n\n## Running Tests\n\n```bash\n# Run all tests\npnpm test\n\n# Run specific preset test\npnpm vitest run test/presets/node.test.ts\n\n# Run unit tests\npnpm vitest run test/unit/\n\n# Run minimal bundle test\npnpm vitest run test/minimal/\n```\n\n## Bug Fix Workflow\n\n1. Write regression test in `test/fixture/` + `test/tests.ts`\n2. Confirm it **fails** (`pnpm vitest run test/presets/node.test.ts`)\n3. Fix the implementation\n4. Confirm it **passes**\n5. Run full suite (`pnpm test`)\n"
  },
  {
    "path": ".agents/vite.md",
    "content": "# Nitro Vite Build System\n\n## Overview\n\n`src/build/vite/` is Nitro's Vite-based build system using Vite 6+ multi-environment API. It integrates as a Vite plugin (`nitro()`) that manages server builds, service environments, dev server, and production output.\n\n## File Map\n\n| File | Purpose |\n|------|---------|\n| `plugin.ts` | Main plugin — 6 sub-plugins orchestrating the build |\n| `env.ts` | Vite environment creation (nitro, services, env-runner) |\n| `dev.ts` | Dev server integration, `FetchableDevEnvironment`, middleware |\n| `prod.ts` | Production multi-env build, asset management, virtual setup module |\n| `bundler.ts` | Rollup/Rolldown config generation |\n| `build.ts` | CLI build entry for `nitro build` (`viteBuild()`) |\n| `preview.ts` | Preview server plugin |\n| `types.ts` | Type definitions (`NitroPluginConfig`, `NitroPluginContext`) |\n\n## Plugin Architecture (`plugin.ts`)\n\n`nitro(config?)` returns an array of 6 sub-plugins:\n\n### 1. `nitroInit` — Context Setup\n- Calls `setupNitroContext()` on first `config` hook\n- Creates Nitro instance via `createNitro()`\n- Detects Rolldown vs Rollup (`_isRolldown`)\n- Resolves bundler config via `getBundlerConfig()`\n- Initializes env-runner in dev mode\n- Attaches rollup plugins for dev environments\n\n### 2. `nitroEnv` — Environment Registration\n- Registers Vite environments: `client`, `nitro`, and user services\n- Auto-detects `entry-server` for SSR\n- Configures per-environment build options (consumer type, externals, etc.)\n\n### 3. `nitroMain` — Build Orchestration\n- Sets app type to `\"custom\"`\n- Configures resolve aliases, server port\n- `buildApp` hook → calls `buildEnvironments()` (production)\n- `generateBundle` hook → tracks entry points\n- `configureServer` → calls `configureViteDevServer()` (dev)\n- `hotUpdate` → server-only module reload\n\n### 4. `nitroPrepare` — Output Cleanup\n- Cleans build directory before build starts\n\n### 5. `nitroService` — Virtual Module Handler\n- Resolves `#nitro-vite-setup` virtual module\n- Provides production setup code for service environments\n\n### 6. `nitroPreviewPlugin` — Preview Server\n- Routes all preview requests through Nitro\n- WebSocket upgrade support\n\n## `setupNitroContext()` Flow\n\n1. Merge plugin config with user config\n2. Load dotenv files\n3. Detect SSR entry (looks for `entry-server.{ts,js,tsx,jsx,mjs}`)\n4. Create Nitro instance (`createNitro()`)\n5. Resolve bundler config (`getBundlerConfig()`)\n6. Initialize env-runner for dev (`initEnvRunner()`)\n\n## Environments (`env.ts`)\n\nNitro uses Vite 6+ environments API for multi-bundle builds:\n\n| Environment | Consumer | Purpose |\n|-------------|----------|---------|\n| `client` | `\"client\"` | Browser HTML/CSS/JS |\n| `nitro` | `\"server\"` | Main server bundle |\n| `ssr` | `\"server\"` | Optional SSR service |\n| Custom | `\"server\"` | User-defined services |\n\n### `createNitroEnvironment()`\n- Consumer: `\"server\"`\n- Uses bundler config (Rollup/Rolldown)\n- Dev: creates `FetchableDevEnvironment` with hot reload\n- Prod: standard environment with minify, sourcemap, commonJS options\n- Resolve: `noExternal` differs for dev vs prod\n- Special conditions: `\"workerd\"` for miniflare, excludes `\"node\"`\n\n### `initEnvRunner()` / `getEnvRunner()`\n- Uses `env-runner` package for worker management\n- Supports Node Worker or Miniflare runtime\n- Auto-restarts on failure (max 3 retries)\n- Custom evaluator for workerd (`AsyncFunction` not allowed)\n- Routes module imports through Vite's transform pipeline\n\n### `reloadEnvRunner()`\n- Triggers full reload of the env-runner worker\n\n## Dev Server (`dev.ts`)\n\n### `FetchableDevEnvironment` (extends `DevEnvironment`)\n- Overrides `fetchModule()` for CJS/ESM resolution\n- For workerd: prevents externalization of bare imports\n- `dispatchFetch()` — routes requests to the dev server worker\n- Sends custom message on init with environment info\n\n### `configureViteDevServer()`\n- Watches Nitro config file for changes (triggers full restart)\n- WebSocket upgrade handling\n- File watchers for route/API/middleware directories (debounced reload)\n- RPC for `transformHTML` messages\n\n### Dev Middleware (`nitroDevMiddleware`)\nTwo-stage request routing:\n\n1. **Pre-processor** — checks if request should go to Nitro:\n   - Skips Vite internal requests (`/@`, `/__`)\n   - Skips file extension requests (`.js`, `.css`, etc.)\n   - Uses `sec-fetch-dest` header for browser detection\n   - Routes to `NitroDevApp` first (static/proxy/dev handlers)\n2. **Main handler** — falls back to env-runner worker for server routes\n\n### Request Flow (Dev)\n```\nBrowser → Vite Dev Server\n  → nitroDevMiddleware (pre-processor)\n    → NitroDevApp (static assets, dev proxy, /_vfs)\n    → env-runner worker (main server logic)\n  → Vite static/HMR (if not handled)\n```\n\n## Production Build (`prod.ts`)\n\n### `buildEnvironments()` — 5 Stages\n\n**Stage 1: Build non-Nitro environments**\n- Client environment (browser bundle)\n- Service environments (SSR, API, custom)\n- Detailed logging per environment\n\n**Stage 2: Renderer template processing**\n- If client input == renderer template, replaces SSR outlet\n- Inlines `globalThis.__nitro_vite_envs__?.[\"ssr\"]?.fetch($REQUEST)`\n- Moves processed template to build dir\n\n**Stage 3: Asset management**\n- Calls `builder.writeAssetsManifest?.()`\n- Registers asset dirs with `max-age=31536000, immutable`\n\n**Stage 4: Build Nitro environment**\n- `prepare()` → clean output\n- Build main server bundle\n- Close Nitro instance\n- Fire `compiled` hook\n- Write build info\n\n**Stage 5: Preview**\n- Start preview server, log success\n\n### `prodSetup()` Virtual Module\nGenerates `#nitro-vite-setup` content:\n```js\n// For each service environment\nglobalThis.__nitro_vite_envs__ = {\n  \"ssr\": { fetch: (...args) => import(\"entry\").then(m => m.default.fetch(...args)) }\n}\n```\n\n## Bundler Config (`bundler.ts`)\n\n`getBundlerConfig()` returns:\n```ts\n{\n  base: BaseBuildConfig,\n  rollupConfig?: RollupConfig,   // if using Rollup\n  rolldownConfig?: RolldownConfig // if using Rolldown\n}\n```\n\nCommon config: ESM output, tree-shaking, chunking, sourcemaps.\n\n**Rolldown-specific**: Transform injection, library chunking, `inlineDynamicImports`/`iife` support.\n**Rollup-specific**: `@rollup/plugin-inject`, `@rollup/plugin-alias`, manual chunk naming.\n\n## HMR (Dev Only)\n\n**Server-only module reload**:\n1. `hotUpdate` hook detects file change\n2. Determines if module is server-only or shared\n3. Server-only → sends `full-reload` to nitro environment\n4. Shared → returns for normal Vite client HMR\n5. Optionally reloads browser (`experimental.vite.serverReload`)\n\n**Directory watchers** (debounced):\n- Routes, API, middleware, plugins, modules dirs\n- Add/delete → full routing rebuild + reload\n\n## Runtime Integration\n\n### Worker Entry (`src/runtime/internal/vite/`)\n\n| File | Purpose |\n|------|---------|\n| `dev-entry.mjs` | Dev entry: polyfills, WebSocket adapter, schedule runner |\n| `dev-worker.mjs` | Worker process: `ViteEnvRunner` class, RPC layer, env management |\n| `ssr-renderer.mjs` | SSR service: calls `fetchViteEnv(\"ssr\", req)` |\n\n### `ViteEnvRunner` (in `dev-worker.mjs`)\n- Manages Vite `ModuleRunner` per environment\n- Loads environment entry via `runner.import()`\n- Routes fetch requests to loaded entries\n- Exposes `__VITE_ENVIRONMENT_RUNNER_IMPORT__` for RSC\n\n### Runtime API (`src/runtime/vite.ts`)\n- `fetchViteEnv(name, input, init)` — route fetch to named Vite environment\n- Accesses `globalThis.__nitro_vite_envs__` registry\n\n## Dev vs Production\n\n| Aspect | Dev | Production |\n|--------|-----|-----------|\n| Runner | env-runner (node-worker / miniflare) | Bundled ESM |\n| HMR | Full reload on file change | N/A |\n| Errors | Interactive error page (Youch) | JSON or minimal HTML |\n| Services | Lazy-loaded via env-runner | Pre-bundled via `prodSetup()` |\n| Template | Dynamic (vite-env route) | Static (inlined SSR outlet) |\n| Sourcemaps | Enabled | Optional |\n\n## Experimental Features\n\n`experimental.vite` options:\n- `assetsImport` (default: true) — `?assets` imports via `@hiogawa/vite-plugin-fullstack`\n- `serverReload` (default: true) — reload on server-only module changes\n- `services` — register custom service environments\n\n## Key Connections\n\n- `src/vite.ts` — public export (`nitro` plugin)\n- `src/build/build.ts` — dispatcher calls `viteBuild()`\n- `src/build/config.ts` — base build config\n- `src/build/plugins.ts` — base build plugins (virtual modules, auto-imports, etc.)\n- `src/build/virtual/` — 14 virtual module templates\n- `src/dev/app.ts` — `NitroDevApp` for dev-only handlers\n- `src/dev/server.ts` — `NitroDevServer` with `RunnerManager`\n- `src/runtime/internal/vite/` — runtime worker and entry points\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "// https://code.visualstudio.com/docs/devcontainers/containers\n// https://containers.dev/implementors/json_reference/\n{\n  \"name\": \"nitro-devcontainer\",\n  \"forwardPorts\": [3000],\n  \"image\": \"node:lts\",\n  \"features\": {},\n  \"customizations\": {\n    \"vscode\": {\n      \"settings\": {},\n      \"extensions\": [\n        \"ms-azuretools.vscode-docker\",\n        \"github.vscode-github-actions\",\n        \"oxc.oxc-vscode\"\n      ]\n    }\n  },\n  \"postStartCommand\": \"npm i -fg corepack && corepack enable && pnpm install && pnpm build --stub\",\n  \"mounts\": [\"type=volume,target=${containerWorkspaceFolder}/node_modules\"]\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\ncharset = utf-8\n\n[*.js]\nindent_style = space\nindent_size = 2\n\n[{package.json,*.yml,*.cjson}]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".eslintcache",
    "content": "[{\"/home/pooya/Code/nitro/AGENTS.md\":\"1\",\"/home/pooya/Code/nitro/CHANGELOG.md\":\"2\",\"/home/pooya/Code/nitro/CLAUDE.md\":\"3\",\"/home/pooya/Code/nitro/CODE_OF_CONDUCT.md\":\"4\",\"/home/pooya/Code/nitro/CONTRIBUTING.md\":\"5\",\"/home/pooya/Code/nitro/README.md\":\"6\",\"/home/pooya/Code/nitro/SECURITY.md\":\"7\",\"/home/pooya/Code/nitro/automd.config.ts\":\"8\",\"/home/pooya/Code/nitro/build.config.ts\":\"9\",\"/home/pooya/Code/nitro/changelog.config.ts\":\"10\",\"/home/pooya/Code/nitro/docs/.config/automd.config.ts\":\"11\",\"/home/pooya/Code/nitro/eslint.config.mjs\":\"12\",\"/home/pooya/Code/nitro/examples/api-routes/api/hello/[name].ts\":\"13\",\"/home/pooya/Code/nitro/examples/api-routes/api/hello.ts\":\"14\",\"/home/pooya/Code/nitro/examples/api-routes/api/test.get.ts\":\"15\",\"/home/pooya/Code/nitro/examples/api-routes/api/test.post.ts\":\"16\",\"/home/pooya/Code/nitro/examples/api-routes/nitro.config.ts\":\"17\",\"/home/pooya/Code/nitro/examples/api-routes/vite.config.ts\":\"18\",\"/home/pooya/Code/nitro/examples/auto-imports/nitro.config.ts\":\"19\",\"/home/pooya/Code/nitro/examples/auto-imports/server/utils/hello.ts\":\"20\",\"/home/pooya/Code/nitro/examples/auto-imports/server.ts\":\"21\",\"/home/pooya/Code/nitro/examples/auto-imports/vite.config.ts\":\"22\",\"/home/pooya/Code/nitro/examples/cached-handler/nitro.config.ts\":\"23\",\"/home/pooya/Code/nitro/examples/cached-handler/server.ts\":\"24\",\"/home/pooya/Code/nitro/examples/cached-handler/vite.config.ts\":\"25\",\"/home/pooya/Code/nitro/examples/custom-error-handler/error.ts\":\"26\",\"/home/pooya/Code/nitro/examples/custom-error-handler/nitro.config.ts\":\"27\",\"/home/pooya/Code/nitro/examples/custom-error-handler/server.ts\":\"28\",\"/home/pooya/Code/nitro/examples/custom-error-handler/vite.config.ts\":\"29\",\"/home/pooya/Code/nitro/examples/database/nitro.config.ts\":\"30\",\"/home/pooya/Code/nitro/examples/database/server.ts\":\"31\",\"/home/pooya/Code/nitro/examples/database/tasks/db/migrate.ts\":\"32\",\"/home/pooya/Code/nitro/examples/database/vite.config.ts\":\"33\",\"/home/pooya/Code/nitro/examples/elysia/nitro.config.ts\":\"34\",\"/home/pooya/Code/nitro/examples/elysia/server.ts\":\"35\",\"/home/pooya/Code/nitro/examples/elysia/vite.config.ts\":\"36\",\"/home/pooya/Code/nitro/examples/express/nitro.config.ts\":\"37\",\"/home/pooya/Code/nitro/examples/express/server.node.ts\":\"38\",\"/home/pooya/Code/nitro/examples/express/vite.config.ts\":\"39\",\"/home/pooya/Code/nitro/examples/fastify/nitro.config.ts\":\"40\",\"/home/pooya/Code/nitro/examples/fastify/server.node.ts\":\"41\",\"/home/pooya/Code/nitro/examples/fastify/vite.config.ts\":\"42\",\"/home/pooya/Code/nitro/examples/hello-world/nitro.config.ts\":\"43\",\"/home/pooya/Code/nitro/examples/hello-world/server.ts\":\"44\",\"/home/pooya/Code/nitro/examples/hello-world/vite.config.ts\":\"45\",\"/home/pooya/Code/nitro/examples/hono/nitro.config.ts\":\"46\",\"/home/pooya/Code/nitro/examples/hono/server.ts\":\"47\",\"/home/pooya/Code/nitro/examples/hono/vite.config.ts\":\"48\",\"/home/pooya/Code/nitro/examples/import-alias/nitro.config.ts\":\"49\",\"/home/pooya/Code/nitro/examples/import-alias/server/routes/index.ts\":\"50\",\"/home/pooya/Code/nitro/examples/import-alias/server/utils/math.ts\":\"51\",\"/home/pooya/Code/nitro/examples/import-alias/vite.config.ts\":\"52\",\"/home/pooya/Code/nitro/examples/middleware/nitro.config.ts\":\"53\",\"/home/pooya/Code/nitro/examples/middleware/server/middleware/auth.ts\":\"54\",\"/home/pooya/Code/nitro/examples/middleware/server.ts\":\"55\",\"/home/pooya/Code/nitro/examples/middleware/vite.config.ts\":\"56\",\"/home/pooya/Code/nitro/examples/mono-jsx/nitro.config.ts\":\"57\",\"/home/pooya/Code/nitro/examples/mono-jsx/server.tsx\":\"58\",\"/home/pooya/Code/nitro/examples/mono-jsx/vite.config.ts\":\"59\",\"/home/pooya/Code/nitro/examples/nano-jsx/nitro.config.ts\":\"60\",\"/home/pooya/Code/nitro/examples/nano-jsx/server.tsx\":\"61\",\"/home/pooya/Code/nitro/examples/nano-jsx/vite.config.ts\":\"62\",\"/home/pooya/Code/nitro/examples/plugins/nitro.config.ts\":\"63\",\"/home/pooya/Code/nitro/examples/plugins/server/plugins/test.ts\":\"64\",\"/home/pooya/Code/nitro/examples/plugins/server.ts\":\"65\",\"/home/pooya/Code/nitro/examples/plugins/vite.config.ts\":\"66\",\"/home/pooya/Code/nitro/examples/renderer/api/hello.ts\":\"67\",\"/home/pooya/Code/nitro/examples/renderer/nitro.config.ts\":\"68\",\"/home/pooya/Code/nitro/examples/renderer/renderer.ts\":\"69\",\"/home/pooya/Code/nitro/examples/renderer/vite.config.ts\":\"70\",\"/home/pooya/Code/nitro/examples/runtime-config/nitro.config.ts\":\"71\",\"/home/pooya/Code/nitro/examples/runtime-config/server.ts\":\"72\",\"/home/pooya/Code/nitro/examples/runtime-config/vite.config.ts\":\"73\",\"/home/pooya/Code/nitro/examples/server-fetch/nitro.config.ts\":\"74\",\"/home/pooya/Code/nitro/examples/server-fetch/routes/hello.ts\":\"75\",\"/home/pooya/Code/nitro/examples/server-fetch/routes/index.ts\":\"76\",\"/home/pooya/Code/nitro/examples/server-fetch/vite.config.ts\":\"77\",\"/home/pooya/Code/nitro/examples/shiki/api/highlight.ts\":\"78\",\"/home/pooya/Code/nitro/examples/shiki/nitro.config.ts\":\"79\",\"/home/pooya/Code/nitro/examples/shiki/vite.config.ts\":\"80\",\"/home/pooya/Code/nitro/examples/virtual-routes/nitro.config.ts\":\"81\",\"/home/pooya/Code/nitro/examples/virtual-routes/vite.config.ts\":\"82\",\"/home/pooya/Code/nitro/examples/vite-nitro-plugin/vite.config.mjs\":\"83\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/action.tsx\":\"84\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/client.tsx\":\"85\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/entry.browser.tsx\":\"86\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/entry.rsc.tsx\":\"87\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/entry.ssr.tsx\":\"88\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/error-boundary.tsx\":\"89\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/request.tsx\":\"90\",\"/home/pooya/Code/nitro/examples/vite-rsc/app/root.tsx\":\"91\",\"/home/pooya/Code/nitro/examples/vite-rsc/vite.config.ts\":\"92\",\"/home/pooya/Code/nitro/examples/vite-ssr-html/app/entry-server.ts\":\"93\",\"/home/pooya/Code/nitro/examples/vite-ssr-html/routes/quote.ts\":\"94\",\"/home/pooya/Code/nitro/examples/vite-ssr-html/vite.config.ts\":\"95\",\"/home/pooya/Code/nitro/examples/vite-ssr-preact/src/app.tsx\":\"96\",\"/home/pooya/Code/nitro/examples/vite-ssr-preact/src/entry-client.tsx\":\"97\",\"/home/pooya/Code/nitro/examples/vite-ssr-preact/src/entry-server.tsx\":\"98\",\"/home/pooya/Code/nitro/examples/vite-ssr-preact/vite.config.mjs\":\"99\",\"/home/pooya/Code/nitro/examples/vite-ssr-react/src/app.tsx\":\"100\",\"/home/pooya/Code/nitro/examples/vite-ssr-react/src/entry-client.tsx\":\"101\",\"/home/pooya/Code/nitro/examples/vite-ssr-react/src/entry-server.tsx\":\"102\",\"/home/pooya/Code/nitro/examples/vite-ssr-react/vite.config.mjs\":\"103\",\"/home/pooya/Code/nitro/examples/vite-ssr-solid/src/app.tsx\":\"104\",\"/home/pooya/Code/nitro/examples/vite-ssr-solid/src/entry-client.tsx\":\"105\",\"/home/pooya/Code/nitro/examples/vite-ssr-solid/src/entry-server.tsx\":\"106\",\"/home/pooya/Code/nitro/examples/vite-ssr-solid/vite.config.mjs\":\"107\",\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/src/main.tsx\":\"108\",\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/src/routes/__root.tsx\":\"109\",\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/src/routes/index.tsx\":\"110\",\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/vite.config.mjs\":\"111\",\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/server.ts\":\"112\",\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/router.tsx\":\"113\",\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/routes/__root.tsx\":\"114\",\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/routes/api/test.ts\":\"115\",\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/routes/index.tsx\":\"116\",\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/vite.config.mjs\":\"117\",\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/entry-client.ts\":\"118\",\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/entry-server.ts\":\"119\",\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/routes.ts\":\"120\",\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/shims.d.ts\":\"121\",\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/vite.config.mjs\":\"122\",\"/home/pooya/Code/nitro/examples/vite-trpc/server/trpc.ts\":\"123\",\"/home/pooya/Code/nitro/examples/vite-trpc/vite.config.ts\":\"124\",\"/home/pooya/Code/nitro/examples/websocket/nitro.config.ts\":\"125\",\"/home/pooya/Code/nitro/examples/websocket/routes/_ws.ts\":\"126\",\"/home/pooya/Code/nitro/examples/websocket/vite.config.ts\":\"127\",\"/home/pooya/Code/nitro/lib/h3.d.mts\":\"128\",\"/home/pooya/Code/nitro/lib/h3.mjs\":\"129\",\"/home/pooya/Code/nitro/lib/vite.types.d.mts\":\"130\",\"/home/pooya/Code/nitro/lib/vite.types.mjs\":\"131\",\"/home/pooya/Code/nitro/playground/nitro.config.ts\":\"132\",\"/home/pooya/Code/nitro/playground/server.ts\":\"133\",\"/home/pooya/Code/nitro/playground/vite.config.ts\":\"134\",\"/home/pooya/Code/nitro/scripts/bump-nightly.ts\":\"135\",\"/home/pooya/Code/nitro/scripts/gen-node-compat.ts\":\"136\",\"/home/pooya/Code/nitro/scripts/gen-presets.ts\":\"137\",\"/home/pooya/Code/nitro/src/build/assets.ts\":\"138\",\"/home/pooya/Code/nitro/src/build/build.ts\":\"139\",\"/home/pooya/Code/nitro/src/build/chunks.ts\":\"140\",\"/home/pooya/Code/nitro/src/build/config.ts\":\"141\",\"/home/pooya/Code/nitro/src/build/info.ts\":\"142\",\"/home/pooya/Code/nitro/src/build/plugins/externals.ts\":\"143\",\"/home/pooya/Code/nitro/src/build/plugins/oxc.ts\":\"144\",\"/home/pooya/Code/nitro/src/build/plugins/raw.ts\":\"145\",\"/home/pooya/Code/nitro/src/build/plugins/route-meta.ts\":\"146\",\"/home/pooya/Code/nitro/src/build/plugins/server-main.ts\":\"147\",\"/home/pooya/Code/nitro/src/build/plugins/sourcemap-min.ts\":\"148\",\"/home/pooya/Code/nitro/src/build/plugins/virtual.ts\":\"149\",\"/home/pooya/Code/nitro/src/build/plugins.ts\":\"150\",\"/home/pooya/Code/nitro/src/build/prepare.ts\":\"151\",\"/home/pooya/Code/nitro/src/build/rolldown/build.ts\":\"152\",\"/home/pooya/Code/nitro/src/build/rolldown/config.ts\":\"153\",\"/home/pooya/Code/nitro/src/build/rolldown/dev.ts\":\"154\",\"/home/pooya/Code/nitro/src/build/rolldown/prod.ts\":\"155\",\"/home/pooya/Code/nitro/src/build/rollup/build.ts\":\"156\",\"/home/pooya/Code/nitro/src/build/rollup/config.ts\":\"157\",\"/home/pooya/Code/nitro/src/build/rollup/dev.ts\":\"158\",\"/home/pooya/Code/nitro/src/build/rollup/error.ts\":\"159\",\"/home/pooya/Code/nitro/src/build/rollup/prod.ts\":\"160\",\"/home/pooya/Code/nitro/src/build/types.ts\":\"161\",\"/home/pooya/Code/nitro/src/build/virtual/_all.ts\":\"162\",\"/home/pooya/Code/nitro/src/build/virtual/database.ts\":\"163\",\"/home/pooya/Code/nitro/src/build/virtual/error-handler.ts\":\"164\",\"/home/pooya/Code/nitro/src/build/virtual/feature-flags.ts\":\"165\",\"/home/pooya/Code/nitro/src/build/virtual/plugins.ts\":\"166\",\"/home/pooya/Code/nitro/src/build/virtual/polyfills.ts\":\"167\",\"/home/pooya/Code/nitro/src/build/virtual/public-assets.ts\":\"168\",\"/home/pooya/Code/nitro/src/build/virtual/renderer-template.ts\":\"169\",\"/home/pooya/Code/nitro/src/build/virtual/routing-meta.ts\":\"170\",\"/home/pooya/Code/nitro/src/build/virtual/routing.ts\":\"171\",\"/home/pooya/Code/nitro/src/build/virtual/runtime-config.ts\":\"172\",\"/home/pooya/Code/nitro/src/build/virtual/server-assets.ts\":\"173\",\"/home/pooya/Code/nitro/src/build/virtual/storage.ts\":\"174\",\"/home/pooya/Code/nitro/src/build/virtual/tasks.ts\":\"175\",\"/home/pooya/Code/nitro/src/build/vite/build.ts\":\"176\",\"/home/pooya/Code/nitro/src/build/vite/bundler.ts\":\"177\",\"/home/pooya/Code/nitro/src/build/vite/dev.ts\":\"178\",\"/home/pooya/Code/nitro/src/build/vite/env.ts\":\"179\",\"/home/pooya/Code/nitro/src/build/vite/plugin.ts\":\"180\",\"/home/pooya/Code/nitro/src/build/vite/preview.ts\":\"181\",\"/home/pooya/Code/nitro/src/build/vite/prod.ts\":\"182\",\"/home/pooya/Code/nitro/src/build/vite/types.ts\":\"183\",\"/home/pooya/Code/nitro/src/builder.ts\":\"184\",\"/home/pooya/Code/nitro/src/cli/commands/build.ts\":\"185\",\"/home/pooya/Code/nitro/src/cli/commands/dev.ts\":\"186\",\"/home/pooya/Code/nitro/src/cli/commands/prepare.ts\":\"187\",\"/home/pooya/Code/nitro/src/cli/commands/task/index.ts\":\"188\",\"/home/pooya/Code/nitro/src/cli/commands/task/list.ts\":\"189\",\"/home/pooya/Code/nitro/src/cli/commands/task/run.ts\":\"190\",\"/home/pooya/Code/nitro/src/cli/common.ts\":\"191\",\"/home/pooya/Code/nitro/src/cli/index.ts\":\"192\",\"/home/pooya/Code/nitro/src/config/defaults.ts\":\"193\",\"/home/pooya/Code/nitro/src/config/loader.ts\":\"194\",\"/home/pooya/Code/nitro/src/config/resolvers/assets.ts\":\"195\",\"/home/pooya/Code/nitro/src/config/resolvers/builder.ts\":\"196\",\"/home/pooya/Code/nitro/src/config/resolvers/compatibility.ts\":\"197\",\"/home/pooya/Code/nitro/src/config/resolvers/database.ts\":\"198\",\"/home/pooya/Code/nitro/src/config/resolvers/error.ts\":\"199\",\"/home/pooya/Code/nitro/src/config/resolvers/export-conditions.ts\":\"200\",\"/home/pooya/Code/nitro/src/config/resolvers/imports.ts\":\"201\",\"/home/pooya/Code/nitro/src/config/resolvers/open-api.ts\":\"202\",\"/home/pooya/Code/nitro/src/config/resolvers/paths.ts\":\"203\",\"/home/pooya/Code/nitro/src/config/resolvers/route-rules.ts\":\"204\",\"/home/pooya/Code/nitro/src/config/resolvers/runtime-config.ts\":\"205\",\"/home/pooya/Code/nitro/src/config/resolvers/storage.ts\":\"206\",\"/home/pooya/Code/nitro/src/config/resolvers/tsconfig.ts\":\"207\",\"/home/pooya/Code/nitro/src/config/resolvers/unenv.ts\":\"208\",\"/home/pooya/Code/nitro/src/config/resolvers/url.ts\":\"209\",\"/home/pooya/Code/nitro/src/config/update.ts\":\"210\",\"/home/pooya/Code/nitro/src/dev/app.ts\":\"211\",\"/home/pooya/Code/nitro/src/dev/server.ts\":\"212\",\"/home/pooya/Code/nitro/src/dev/vfs.ts\":\"213\",\"/home/pooya/Code/nitro/src/global.ts\":\"214\",\"/home/pooya/Code/nitro/src/module.ts\":\"215\",\"/home/pooya/Code/nitro/src/nitro.ts\":\"216\",\"/home/pooya/Code/nitro/src/prerender/prerender.ts\":\"217\",\"/home/pooya/Code/nitro/src/prerender/utils.ts\":\"218\",\"/home/pooya/Code/nitro/src/presets/_nitro/base-worker.ts\":\"219\",\"/home/pooya/Code/nitro/src/presets/_nitro/nitro-dev.ts\":\"220\",\"/home/pooya/Code/nitro/src/presets/_nitro/nitro-prerender.ts\":\"221\",\"/home/pooya/Code/nitro/src/presets/_nitro/preset.ts\":\"222\",\"/home/pooya/Code/nitro/src/presets/_nitro/runtime/nitro-dev.ts\":\"223\",\"/home/pooya/Code/nitro/src/presets/_nitro/runtime/nitro-prerenderer.ts\":\"224\",\"/home/pooya/Code/nitro/src/presets/_nitro/runtime/service-worker.ts\":\"225\",\"/home/pooya/Code/nitro/src/presets/_resolve.ts\":\"226\",\"/home/pooya/Code/nitro/src/presets/_static/preset.ts\":\"227\",\"/home/pooya/Code/nitro/src/presets/_utils/fs.ts\":\"228\",\"/home/pooya/Code/nitro/src/presets/_utils/preset.ts\":\"229\",\"/home/pooya/Code/nitro/src/presets/alwaysdata/preset.ts\":\"230\",\"/home/pooya/Code/nitro/src/presets/aws-amplify/preset.ts\":\"231\",\"/home/pooya/Code/nitro/src/presets/aws-amplify/runtime/aws-amplify.ts\":\"232\",\"/home/pooya/Code/nitro/src/presets/aws-amplify/types.ts\":\"233\",\"/home/pooya/Code/nitro/src/presets/aws-amplify/utils.ts\":\"234\",\"/home/pooya/Code/nitro/src/presets/aws-lambda/preset.ts\":\"235\",\"/home/pooya/Code/nitro/src/presets/aws-lambda/runtime/_utils.ts\":\"236\",\"/home/pooya/Code/nitro/src/presets/aws-lambda/runtime/aws-lambda-streaming.ts\":\"237\",\"/home/pooya/Code/nitro/src/presets/aws-lambda/runtime/aws-lambda.ts\":\"238\",\"/home/pooya/Code/nitro/src/presets/aws-lambda/types.ts\":\"239\",\"/home/pooya/Code/nitro/src/presets/azure/preset.ts\":\"240\",\"/home/pooya/Code/nitro/src/presets/azure/runtime/_utils.ts\":\"241\",\"/home/pooya/Code/nitro/src/presets/azure/runtime/azure-swa.ts\":\"242\",\"/home/pooya/Code/nitro/src/presets/azure/types.ts\":\"243\",\"/home/pooya/Code/nitro/src/presets/azure/utils.ts\":\"244\",\"/home/pooya/Code/nitro/src/presets/bun/preset.ts\":\"245\",\"/home/pooya/Code/nitro/src/presets/bun/runtime/bun.ts\":\"246\",\"/home/pooya/Code/nitro/src/presets/cleavr/preset.ts\":\"247\",\"/home/pooya/Code/nitro/src/presets/cloudflare/dev.ts\":\"248\",\"/home/pooya/Code/nitro/src/presets/cloudflare/entry-exports.ts\":\"249\",\"/home/pooya/Code/nitro/src/presets/cloudflare/preset.ts\":\"250\",\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/_module-handler.ts\":\"251\",\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/cloudflare-durable.ts\":\"252\",\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/cloudflare-module.ts\":\"253\",\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/cloudflare-pages.ts\":\"254\",\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/plugin.dev.ts\":\"255\",\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/shims/workers.dev.mjs\":\"256\",\"/home/pooya/Code/nitro/src/presets/cloudflare/types.ts\":\"257\",\"/home/pooya/Code/nitro/src/presets/cloudflare/unenv/node-compat.ts\":\"258\",\"/home/pooya/Code/nitro/src/presets/cloudflare/unenv/preset.ts\":\"259\",\"/home/pooya/Code/nitro/src/presets/cloudflare/utils.ts\":\"260\",\"/home/pooya/Code/nitro/src/presets/cloudflare/wrangler/_utils.ts\":\"261\",\"/home/pooya/Code/nitro/src/presets/cloudflare/wrangler/config.ts\":\"262\",\"/home/pooya/Code/nitro/src/presets/cloudflare/wrangler/environment.ts\":\"263\",\"/home/pooya/Code/nitro/src/presets/deno/preset.ts\":\"264\",\"/home/pooya/Code/nitro/src/presets/deno/runtime/deno-deploy.ts\":\"265\",\"/home/pooya/Code/nitro/src/presets/deno/runtime/deno-server.ts\":\"266\",\"/home/pooya/Code/nitro/src/presets/deno/unenv/node-compat.ts\":\"267\",\"/home/pooya/Code/nitro/src/presets/deno/unenv/preset.ts\":\"268\",\"/home/pooya/Code/nitro/src/presets/digitalocean/preset.ts\":\"269\",\"/home/pooya/Code/nitro/src/presets/firebase/preset.ts\":\"270\",\"/home/pooya/Code/nitro/src/presets/firebase/types.ts\":\"271\",\"/home/pooya/Code/nitro/src/presets/flightcontrol/preset.ts\":\"272\",\"/home/pooya/Code/nitro/src/presets/genezio/preset.ts\":\"273\",\"/home/pooya/Code/nitro/src/presets/heroku/preset.ts\":\"274\",\"/home/pooya/Code/nitro/src/presets/iis/preset.ts\":\"275\",\"/home/pooya/Code/nitro/src/presets/iis/utils.ts\":\"276\",\"/home/pooya/Code/nitro/src/presets/index.ts\":\"277\",\"/home/pooya/Code/nitro/src/presets/koyeb/preset.ts\":\"278\",\"/home/pooya/Code/nitro/src/presets/netlify/preset.ts\":\"279\",\"/home/pooya/Code/nitro/src/presets/netlify/runtime/netlify-edge.ts\":\"280\",\"/home/pooya/Code/nitro/src/presets/netlify/runtime/netlify.ts\":\"281\",\"/home/pooya/Code/nitro/src/presets/netlify/types.ts\":\"282\",\"/home/pooya/Code/nitro/src/presets/netlify/utils.ts\":\"283\",\"/home/pooya/Code/nitro/src/presets/node/cluster.ts\":\"284\",\"/home/pooya/Code/nitro/src/presets/node/preset.ts\":\"285\",\"/home/pooya/Code/nitro/src/presets/node/runtime/node-cluster.ts\":\"286\",\"/home/pooya/Code/nitro/src/presets/node/runtime/node-middleware.ts\":\"287\",\"/home/pooya/Code/nitro/src/presets/node/runtime/node-server.ts\":\"288\",\"/home/pooya/Code/nitro/src/presets/platform.sh/preset.ts\":\"289\",\"/home/pooya/Code/nitro/src/presets/render.com/preset.ts\":\"290\",\"/home/pooya/Code/nitro/src/presets/standard/preset.ts\":\"291\",\"/home/pooya/Code/nitro/src/presets/standard/runtime/server.ts\":\"292\",\"/home/pooya/Code/nitro/src/presets/stormkit/preset.ts\":\"293\",\"/home/pooya/Code/nitro/src/presets/stormkit/runtime/stormkit.ts\":\"294\",\"/home/pooya/Code/nitro/src/presets/vercel/preset.ts\":\"295\",\"/home/pooya/Code/nitro/src/presets/vercel/runtime/isr.ts\":\"296\",\"/home/pooya/Code/nitro/src/presets/vercel/runtime/vercel.node.ts\":\"297\",\"/home/pooya/Code/nitro/src/presets/vercel/runtime/vercel.web.ts\":\"298\",\"/home/pooya/Code/nitro/src/presets/vercel/types.ts\":\"299\",\"/home/pooya/Code/nitro/src/presets/vercel/utils.ts\":\"300\",\"/home/pooya/Code/nitro/src/presets/winterjs/preset.ts\":\"301\",\"/home/pooya/Code/nitro/src/presets/winterjs/runtime/winterjs.ts\":\"302\",\"/home/pooya/Code/nitro/src/presets/zeabur/preset.ts\":\"303\",\"/home/pooya/Code/nitro/src/presets/zeabur/runtime/zeabur.ts\":\"304\",\"/home/pooya/Code/nitro/src/presets/zerops/preset.ts\":\"305\",\"/home/pooya/Code/nitro/src/routing.ts\":\"306\",\"/home/pooya/Code/nitro/src/runner/node.ts\":\"307\",\"/home/pooya/Code/nitro/src/runner/proxy.ts\":\"308\",\"/home/pooya/Code/nitro/src/runtime/app.ts\":\"309\",\"/home/pooya/Code/nitro/src/runtime/cache.ts\":\"310\",\"/home/pooya/Code/nitro/src/runtime/config.ts\":\"311\",\"/home/pooya/Code/nitro/src/runtime/context.ts\":\"312\",\"/home/pooya/Code/nitro/src/runtime/database.ts\":\"313\",\"/home/pooya/Code/nitro/src/runtime/internal/app.ts\":\"314\",\"/home/pooya/Code/nitro/src/runtime/internal/cache.ts\":\"315\",\"/home/pooya/Code/nitro/src/runtime/internal/context.ts\":\"316\",\"/home/pooya/Code/nitro/src/runtime/internal/database.ts\":\"317\",\"/home/pooya/Code/nitro/src/runtime/internal/empty.ts\":\"318\",\"/home/pooya/Code/nitro/src/runtime/internal/error/dev.ts\":\"319\",\"/home/pooya/Code/nitro/src/runtime/internal/error/hooks.ts\":\"320\",\"/home/pooya/Code/nitro/src/runtime/internal/error/prod.ts\":\"321\",\"/home/pooya/Code/nitro/src/runtime/internal/error/utils.ts\":\"322\",\"/home/pooya/Code/nitro/src/runtime/internal/meta.ts\":\"323\",\"/home/pooya/Code/nitro/src/runtime/internal/plugin.ts\":\"324\",\"/home/pooya/Code/nitro/src/runtime/internal/route-rules.ts\":\"325\",\"/home/pooya/Code/nitro/src/runtime/internal/routes/dev-tasks.ts\":\"326\",\"/home/pooya/Code/nitro/src/runtime/internal/routes/openapi.ts\":\"327\",\"/home/pooya/Code/nitro/src/runtime/internal/routes/renderer-template.dev.ts\":\"328\",\"/home/pooya/Code/nitro/src/runtime/internal/routes/renderer-template.ts\":\"329\",\"/home/pooya/Code/nitro/src/runtime/internal/routes/scalar.ts\":\"330\",\"/home/pooya/Code/nitro/src/runtime/internal/routes/swagger.ts\":\"331\",\"/home/pooya/Code/nitro/src/runtime/internal/runtime-config.ts\":\"332\",\"/home/pooya/Code/nitro/src/runtime/internal/static.ts\":\"333\",\"/home/pooya/Code/nitro/src/runtime/internal/storage.ts\":\"334\",\"/home/pooya/Code/nitro/src/runtime/internal/task.ts\":\"335\",\"/home/pooya/Code/nitro/src/runtime/internal/vite/dev-entry.mjs\":\"336\",\"/home/pooya/Code/nitro/src/runtime/internal/vite/node-runner.mjs\":\"337\",\"/home/pooya/Code/nitro/src/runtime/internal/vite/ssr-renderer.mjs\":\"338\",\"/home/pooya/Code/nitro/src/runtime/meta.ts\":\"339\",\"/home/pooya/Code/nitro/src/runtime/nitro.ts\":\"340\",\"/home/pooya/Code/nitro/src/runtime/runtime-config.ts\":\"341\",\"/home/pooya/Code/nitro/src/runtime/storage.ts\":\"342\",\"/home/pooya/Code/nitro/src/runtime/task.ts\":\"343\",\"/home/pooya/Code/nitro/src/runtime/virtual/_runtime_warn.ts\":\"344\",\"/home/pooya/Code/nitro/src/runtime/virtual/database.ts\":\"345\",\"/home/pooya/Code/nitro/src/runtime/virtual/error-handler.ts\":\"346\",\"/home/pooya/Code/nitro/src/runtime/virtual/feature-flags.ts\":\"347\",\"/home/pooya/Code/nitro/src/runtime/virtual/plugins.ts\":\"348\",\"/home/pooya/Code/nitro/src/runtime/virtual/polyfills.ts\":\"349\",\"/home/pooya/Code/nitro/src/runtime/virtual/public-assets.ts\":\"350\",\"/home/pooya/Code/nitro/src/runtime/virtual/renderer-template.ts\":\"351\",\"/home/pooya/Code/nitro/src/runtime/virtual/routing-meta.ts\":\"352\",\"/home/pooya/Code/nitro/src/runtime/virtual/routing.ts\":\"353\",\"/home/pooya/Code/nitro/src/runtime/virtual/runtime-config.ts\":\"354\",\"/home/pooya/Code/nitro/src/runtime/virtual/server-assets.ts\":\"355\",\"/home/pooya/Code/nitro/src/runtime/virtual/storage.ts\":\"356\",\"/home/pooya/Code/nitro/src/runtime/virtual/tasks.ts\":\"357\",\"/home/pooya/Code/nitro/src/runtime/vite.ts\":\"358\",\"/home/pooya/Code/nitro/src/scan.ts\":\"359\",\"/home/pooya/Code/nitro/src/task.ts\":\"360\",\"/home/pooya/Code/nitro/src/types/_utils.ts\":\"361\",\"/home/pooya/Code/nitro/src/types/build.ts\":\"362\",\"/home/pooya/Code/nitro/src/types/config.ts\":\"363\",\"/home/pooya/Code/nitro/src/types/fetch/_match.ts\":\"364\",\"/home/pooya/Code/nitro/src/types/fetch/_serialize.ts\":\"365\",\"/home/pooya/Code/nitro/src/types/fetch/fetch.ts\":\"366\",\"/home/pooya/Code/nitro/src/types/fetch/index.ts\":\"367\",\"/home/pooya/Code/nitro/src/types/global.ts\":\"368\",\"/home/pooya/Code/nitro/src/types/h3.ts\":\"369\",\"/home/pooya/Code/nitro/src/types/handler.ts\":\"370\",\"/home/pooya/Code/nitro/src/types/hooks.ts\":\"371\",\"/home/pooya/Code/nitro/src/types/index.ts\":\"372\",\"/home/pooya/Code/nitro/src/types/module.ts\":\"373\",\"/home/pooya/Code/nitro/src/types/nitro.ts\":\"374\",\"/home/pooya/Code/nitro/src/types/openapi-ts.ts\":\"375\",\"/home/pooya/Code/nitro/src/types/openapi.ts\":\"376\",\"/home/pooya/Code/nitro/src/types/prerender.ts\":\"377\",\"/home/pooya/Code/nitro/src/types/preset.ts\":\"378\",\"/home/pooya/Code/nitro/src/types/route-rules.ts\":\"379\",\"/home/pooya/Code/nitro/src/types/runner.ts\":\"380\",\"/home/pooya/Code/nitro/src/types/runtime/asset.ts\":\"381\",\"/home/pooya/Code/nitro/src/types/runtime/cache.ts\":\"382\",\"/home/pooya/Code/nitro/src/types/runtime/index.ts\":\"383\",\"/home/pooya/Code/nitro/src/types/runtime/nitro.ts\":\"384\",\"/home/pooya/Code/nitro/src/types/runtime/task.ts\":\"385\",\"/home/pooya/Code/nitro/src/types/srvx.ts\":\"386\",\"/home/pooya/Code/nitro/src/utils/compress.ts\":\"387\",\"/home/pooya/Code/nitro/src/utils/dep.ts\":\"388\",\"/home/pooya/Code/nitro/src/utils/fs-tree.ts\":\"389\",\"/home/pooya/Code/nitro/src/utils/fs.ts\":\"390\",\"/home/pooya/Code/nitro/src/utils/parallel.ts\":\"391\",\"/home/pooya/Code/nitro/src/utils/regex.ts\":\"392\",\"/home/pooya/Code/nitro/src/vite.ts\":\"393\",\"/home/pooya/Code/nitro/test/examples.test.ts\":\"394\",\"/home/pooya/Code/nitro/test/fixture/error.ts\":\"395\",\"/home/pooya/Code/nitro/test/fixture/exports.cloudflare.ts\":\"396\",\"/home/pooya/Code/nitro/test/fixture/nitro.config.ts\":\"397\",\"/home/pooya/Code/nitro/test/fixture/public/foo.js\":\"398\",\"/home/pooya/Code/nitro/test/fixture/server/files/sqlts.sql.ts\":\"399\",\"/home/pooya/Code/nitro/test/fixture/server/middleware/_ignored.ts\":\"400\",\"/home/pooya/Code/nitro/test/fixture/server/plugins/errors.ts\":\"401\",\"/home/pooya/Code/nitro/test/fixture/server/plugins/vary.ts\":\"402\",\"/home/pooya/Code/nitro/test/fixture/server/routes/(route-group)/route-group.ts\":\"403\",\"/home/pooya/Code/nitro/test/fixture/server/routes/500.ts\":\"404\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/_ignored.ts\":\"405\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/cached.ts\":\"406\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/db.ts\":\"407\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/echo.ts\":\"408\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/error.ts\":\"409\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/errors.ts\":\"410\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/headers.ts\":\"411\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/hello.ts\":\"412\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/hey/index.get.ts\":\"413\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/kebab.ts\":\"414\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/meta/test.ts\":\"415\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/methods/foo.get.get.ts\":\"416\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/methods/get.ts\":\"417\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/param/[test-id].ts\":\"418\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/storage/item.get.ts\":\"419\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/storage/item.put.ts\":\"420\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/upload.post.ts\":\"421\",\"/home/pooya/Code/nitro/test/fixture/server/routes/api/wildcard/[...param].ts\":\"422\",\"/home/pooya/Code/nitro/test/fixture/server/routes/assets/[id].ts\":\"423\",\"/home/pooya/Code/nitro/test/fixture/server/routes/assets/all.ts\":\"424\",\"/home/pooya/Code/nitro/test/fixture/server/routes/assets/md.ts\":\"425\",\"/home/pooya/Code/nitro/test/fixture/server/routes/config.ts\":\"426\",\"/home/pooya/Code/nitro/test/fixture/server/routes/context.ts\":\"427\",\"/home/pooya/Code/nitro/test/fixture/server/routes/env/index.dev.ts\":\"428\",\"/home/pooya/Code/nitro/test/fixture/server/routes/env/index.get.prod.ts\":\"429\",\"/home/pooya/Code/nitro/test/fixture/server/routes/error-stack.ts\":\"430\",\"/home/pooya/Code/nitro/test/fixture/server/routes/fetch.ts\":\"431\",\"/home/pooya/Code/nitro/test/fixture/server/routes/file.ts\":\"432\",\"/home/pooya/Code/nitro/test/fixture/server/routes/icon.png.ts\":\"433\",\"/home/pooya/Code/nitro/test/fixture/server/routes/imports.ts\":\"434\",\"/home/pooya/Code/nitro/test/fixture/server/routes/json-string.ts\":\"435\",\"/home/pooya/Code/nitro/test/fixture/server/routes/jsx.tsx\":\"436\",\"/home/pooya/Code/nitro/test/fixture/server/routes/modules.ts\":\"437\",\"/home/pooya/Code/nitro/test/fixture/server/routes/node-compat.ts\":\"438\",\"/home/pooya/Code/nitro/test/fixture/server/routes/prerender-custom.html.ts\":\"439\",\"/home/pooya/Code/nitro/test/fixture/server/routes/prerender.ts\":\"440\",\"/home/pooya/Code/nitro/test/fixture/server/routes/raw.ts\":\"441\",\"/home/pooya/Code/nitro/test/fixture/server/routes/replace.ts\":\"442\",\"/home/pooya/Code/nitro/test/fixture/server/routes/rules/[...slug].ts\":\"443\",\"/home/pooya/Code/nitro/test/fixture/server/routes/static-flags.ts\":\"444\",\"/home/pooya/Code/nitro/test/fixture/server/routes/stream.ts\":\"445\",\"/home/pooya/Code/nitro/test/fixture/server/routes/tasks/[...name].ts\":\"446\",\"/home/pooya/Code/nitro/test/fixture/server/routes/wait-until.ts\":\"447\",\"/home/pooya/Code/nitro/test/fixture/server/routes/wasm/dynamic-import.ts\":\"448\",\"/home/pooya/Code/nitro/test/fixture/server/routes/wasm/static-import.ts\":\"449\",\"/home/pooya/Code/nitro/test/fixture/server/tasks/db/migrate.ts\":\"450\",\"/home/pooya/Code/nitro/test/fixture/server/tasks/test.ts\":\"451\",\"/home/pooya/Code/nitro/test/fixture/server/utils/foo/bar/test.ts\":\"452\",\"/home/pooya/Code/nitro/test/fixture/server/utils/foo/test.ts\":\"453\",\"/home/pooya/Code/nitro/test/fixture/server/utils/test.ts\":\"454\",\"/home/pooya/Code/nitro/test/fixture/server.config.ts\":\"455\",\"/home/pooya/Code/nitro/test/fixture/server.ts\":\"456\",\"/home/pooya/Code/nitro/test/fixture/vite.config.ts\":\"457\",\"/home/pooya/Code/nitro/test/minimal/minimal.test.ts\":\"458\",\"/home/pooya/Code/nitro/test/minimal/nitro.config.ts\":\"459\",\"/home/pooya/Code/nitro/test/minimal/server.ts\":\"460\",\"/home/pooya/Code/nitro/test/minimal/vite.config.mjs\":\"461\",\"/home/pooya/Code/nitro/test/presets/aws-lambda.test.ts\":\"462\",\"/home/pooya/Code/nitro/test/presets/azure-swa.test.ts\":\"463\",\"/home/pooya/Code/nitro/test/presets/bun.test.ts\":\"464\",\"/home/pooya/Code/nitro/test/presets/cloudflare-module.test.ts\":\"465\",\"/home/pooya/Code/nitro/test/presets/cloudflare-pages.test.ts\":\"466\",\"/home/pooya/Code/nitro/test/presets/deno-server.test.ts\":\"467\",\"/home/pooya/Code/nitro/test/presets/netlify.test.ts\":\"468\",\"/home/pooya/Code/nitro/test/presets/nitro-dev.test.ts\":\"469\",\"/home/pooya/Code/nitro/test/presets/node.test.ts\":\"470\",\"/home/pooya/Code/nitro/test/presets/standard.test.ts\":\"471\",\"/home/pooya/Code/nitro/test/presets/static.test.ts\":\"472\",\"/home/pooya/Code/nitro/test/presets/vercel.test.ts\":\"473\",\"/home/pooya/Code/nitro/test/presets/winterjs.test.ts\":\"474\",\"/home/pooya/Code/nitro/test/scripts/gen-fixture-types.ts\":\"475\",\"/home/pooya/Code/nitro/test/tests.ts\":\"476\",\"/home/pooya/Code/nitro/test/unit/azure.utils.test.ts\":\"477\",\"/home/pooya/Code/nitro/test/unit/runtime-config.env.test.ts\":\"478\",\"/home/pooya/Code/nitro/test/unit/runtime-config.test.ts\":\"479\",\"/home/pooya/Code/nitro/test/unit/virtual.test.ts\":\"480\",\"/home/pooya/Code/nitro/vitest.config.ts\":\"481\"},{\"size\":6278,\"mtime\":1768935766630,\"results\":\"482\",\"hashOfConfig\":\"483\"},{\"size\":11098,\"mtime\":1769020993118,\"results\":\"484\",\"hashOfConfig\":\"483\"},{\"size\":11,\"mtime\":1768935766630,\"results\":\"485\",\"hashOfConfig\":\"483\"},{\"size\":5220,\"mtime\":1768485628956,\"results\":\"486\",\"hashOfConfig\":\"483\"},{\"size\":2878,\"mtime\":1768485628956,\"results\":\"487\",\"hashOfConfig\":\"483\"},{\"size\":658,\"mtime\":1769019507194,\"results\":\"488\",\"hashOfConfig\":\"483\"},{\"size\":622,\"mtime\":1768485628956,\"results\":\"489\",\"hashOfConfig\":\"483\"},{\"size\":726,\"mtime\":1768485628956,\"results\":\"490\",\"hashOfConfig\":\"491\"},{\"size\":5625,\"mtime\":1768935766630,\"results\":\"492\",\"hashOfConfig\":\"491\"},{\"size\":200,\"mtime\":1769103053294,\"results\":\"493\",\"hashOfConfig\":\"491\"},{\"size\":47,\"mtime\":1765885654431,\"results\":\"494\",\"hashOfConfig\":\"491\"},{\"size\":585,\"mtime\":1768935766633,\"results\":\"495\",\"hashOfConfig\":\"496\"},{\"size\":137,\"mtime\":1768485628958,\"results\":\"497\",\"hashOfConfig\":\"491\"},{\"size\":100,\"mtime\":1768485628958,\"results\":\"498\",\"hashOfConfig\":\"491\"},{\"size\":99,\"mtime\":1768485628958,\"results\":\"499\",\"hashOfConfig\":\"491\"},{\"size\":188,\"mtime\":1768485628958,\"results\":\"500\",\"hashOfConfig\":\"491\"},{\"size\":92,\"mtime\":1768485628958,\"results\":\"501\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628958,\"results\":\"502\",\"hashOfConfig\":\"491\"},{\"size\":107,\"mtime\":1768485628958,\"results\":\"503\",\"hashOfConfig\":\"491\"},{\"size\":75,\"mtime\":1768485628959,\"results\":\"504\",\"hashOfConfig\":\"491\"},{\"size\":172,\"mtime\":1768485628958,\"results\":\"505\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"506\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628959,\"results\":\"507\",\"hashOfConfig\":\"491\"},{\"size\":428,\"mtime\":1768485628959,\"results\":\"508\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"509\",\"hashOfConfig\":\"491\"},{\"size\":240,\"mtime\":1768485628959,\"results\":\"510\",\"hashOfConfig\":\"491\"},{\"size\":178,\"mtime\":1768485628959,\"results\":\"511\",\"hashOfConfig\":\"491\"},{\"size\":153,\"mtime\":1768485628959,\"results\":\"512\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"513\",\"hashOfConfig\":\"491\"},{\"size\":190,\"mtime\":1768485628959,\"results\":\"514\",\"hashOfConfig\":\"491\"},{\"size\":635,\"mtime\":1768485628959,\"results\":\"515\",\"hashOfConfig\":\"491\"},{\"size\":548,\"mtime\":1768485628959,\"results\":\"516\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"517\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628959,\"results\":\"518\",\"hashOfConfig\":\"491\"},{\"size\":141,\"mtime\":1768485628959,\"results\":\"519\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"520\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628959,\"results\":\"521\",\"hashOfConfig\":\"491\"},{\"size\":157,\"mtime\":1768870633712,\"results\":\"522\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"523\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628959,\"results\":\"524\",\"hashOfConfig\":\"491\"},{\"size\":155,\"mtime\":1768485628959,\"results\":\"525\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"526\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628959,\"results\":\"527\",\"hashOfConfig\":\"491\"},{\"size\":90,\"mtime\":1768485628959,\"results\":\"528\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"529\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628959,\"results\":\"530\",\"hashOfConfig\":\"491\"},{\"size\":146,\"mtime\":1768485628959,\"results\":\"531\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628959,\"results\":\"532\",\"hashOfConfig\":\"491\"},{\"size\":140,\"mtime\":1768485628959,\"results\":\"533\",\"hashOfConfig\":\"491\"},{\"size\":239,\"mtime\":1768485628960,\"results\":\"534\",\"hashOfConfig\":\"491\"},{\"size\":190,\"mtime\":1768485628960,\"results\":\"535\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"536\",\"hashOfConfig\":\"491\"},{\"size\":92,\"mtime\":1768485628960,\"results\":\"537\",\"hashOfConfig\":\"491\"},{\"size\":171,\"mtime\":1768485628960,\"results\":\"538\",\"hashOfConfig\":\"491\"},{\"size\":119,\"mtime\":1768485628960,\"results\":\"539\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"540\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628960,\"results\":\"541\",\"hashOfConfig\":\"491\"},{\"size\":83,\"mtime\":1768485628960,\"results\":\"542\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"543\",\"hashOfConfig\":\"491\"},{\"size\":72,\"mtime\":1768485628960,\"results\":\"544\",\"hashOfConfig\":\"491\"},{\"size\":188,\"mtime\":1768485628960,\"results\":\"545\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"546\",\"hashOfConfig\":\"491\"},{\"size\":92,\"mtime\":1768485628960,\"results\":\"547\",\"hashOfConfig\":\"491\"},{\"size\":269,\"mtime\":1768485628960,\"results\":\"548\",\"hashOfConfig\":\"491\"},{\"size\":96,\"mtime\":1768485628960,\"results\":\"549\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"550\",\"hashOfConfig\":\"491\"},{\"size\":100,\"mtime\":1768485628960,\"results\":\"551\",\"hashOfConfig\":\"491\"},{\"size\":131,\"mtime\":1768485628960,\"results\":\"552\",\"hashOfConfig\":\"491\"},{\"size\":533,\"mtime\":1768485628960,\"results\":\"553\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"554\",\"hashOfConfig\":\"491\"},{\"size\":132,\"mtime\":1768485628960,\"results\":\"555\",\"hashOfConfig\":\"491\"},{\"size\":218,\"mtime\":1768485628960,\"results\":\"556\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628960,\"results\":\"557\",\"hashOfConfig\":\"491\"},{\"size\":315,\"mtime\":1768485628960,\"results\":\"558\",\"hashOfConfig\":\"491\"},{\"size\":89,\"mtime\":1768485628960,\"results\":\"559\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628961,\"results\":\"560\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628961,\"results\":\"561\",\"hashOfConfig\":\"491\"},{\"size\":621,\"mtime\":1768485628961,\"results\":\"562\",\"hashOfConfig\":\"491\"},{\"size\":92,\"mtime\":1768485628961,\"results\":\"563\",\"hashOfConfig\":\"491\"},{\"size\":130,\"mtime\":1768485628961,\"results\":\"564\",\"hashOfConfig\":\"491\"},{\"size\":244,\"mtime\":1768485628961,\"results\":\"565\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628961,\"results\":\"566\",\"hashOfConfig\":\"491\"},{\"size\":440,\"mtime\":1768485628961,\"results\":\"567\",\"hashOfConfig\":\"496\"},{\"size\":198,\"mtime\":1768935766633,\"results\":\"568\",\"hashOfConfig\":\"491\"},{\"size\":247,\"mtime\":1768935766633,\"results\":\"569\",\"hashOfConfig\":\"491\"},{\"size\":4359,\"mtime\":1768935766633,\"results\":\"570\",\"hashOfConfig\":\"491\"},{\"size\":4641,\"mtime\":1768935766634,\"results\":\"571\",\"hashOfConfig\":\"491\"},{\"size\":2850,\"mtime\":1768935766634,\"results\":\"572\",\"hashOfConfig\":\"491\"},{\"size\":2258,\"mtime\":1768935766634,\"results\":\"573\",\"hashOfConfig\":\"491\"},{\"size\":1889,\"mtime\":1768935766634,\"results\":\"574\",\"hashOfConfig\":\"491\"},{\"size\":2353,\"mtime\":1768935766634,\"results\":\"575\",\"hashOfConfig\":\"491\"},{\"size\":567,\"mtime\":1768935766634,\"results\":\"576\",\"hashOfConfig\":\"491\"},{\"size\":748,\"mtime\":1768485628961,\"results\":\"577\",\"hashOfConfig\":\"491\"},{\"size\":570,\"mtime\":1768485628961,\"results\":\"578\",\"hashOfConfig\":\"491\"},{\"size\":234,\"mtime\":1768485628961,\"results\":\"579\",\"hashOfConfig\":\"491\"},{\"size\":202,\"mtime\":1768485628961,\"results\":\"580\",\"hashOfConfig\":\"491\"},{\"size\":150,\"mtime\":1768485628962,\"results\":\"581\",\"hashOfConfig\":\"491\"},{\"size\":1223,\"mtime\":1768485628962,\"results\":\"582\",\"hashOfConfig\":\"491\"},{\"size\":329,\"mtime\":1768485628962,\"results\":\"583\",\"hashOfConfig\":\"496\"},{\"size\":265,\"mtime\":1768485628962,\"results\":\"584\",\"hashOfConfig\":\"491\"},{\"size\":177,\"mtime\":1768485628962,\"results\":\"585\",\"hashOfConfig\":\"491\"},{\"size\":1062,\"mtime\":1768485628962,\"results\":\"586\",\"hashOfConfig\":\"491\"},{\"size\":294,\"mtime\":1768485628962,\"results\":\"587\",\"hashOfConfig\":\"496\"},{\"size\":283,\"mtime\":1768485628962,\"results\":\"588\",\"hashOfConfig\":\"491\"},{\"size\":154,\"mtime\":1768485628962,\"results\":\"589\",\"hashOfConfig\":\"491\"},{\"size\":1192,\"mtime\":1768485628962,\"results\":\"590\",\"hashOfConfig\":\"491\"},{\"size\":452,\"mtime\":1768485628962,\"results\":\"591\",\"hashOfConfig\":\"496\"},{\"size\":706,\"mtime\":1768485628962,\"results\":\"592\",\"hashOfConfig\":\"491\"},{\"size\":439,\"mtime\":1768485628962,\"results\":\"593\",\"hashOfConfig\":\"491\"},{\"size\":364,\"mtime\":1768485628962,\"results\":\"594\",\"hashOfConfig\":\"491\"},{\"size\":323,\"mtime\":1768485628962,\"results\":\"595\",\"hashOfConfig\":\"496\"},{\"size\":180,\"mtime\":1768485628962,\"results\":\"596\",\"hashOfConfig\":\"491\"},{\"size\":390,\"mtime\":1768485628962,\"results\":\"597\",\"hashOfConfig\":\"491\"},{\"size\":1475,\"mtime\":1768485628962,\"results\":\"598\",\"hashOfConfig\":\"491\"},{\"size\":511,\"mtime\":1768485628962,\"results\":\"599\",\"hashOfConfig\":\"491\"},{\"size\":266,\"mtime\":1768485628962,\"results\":\"600\",\"hashOfConfig\":\"491\"},{\"size\":553,\"mtime\":1768485628962,\"results\":\"601\",\"hashOfConfig\":\"496\"},{\"size\":422,\"mtime\":1768485628962,\"results\":\"602\",\"hashOfConfig\":\"491\"},{\"size\":1784,\"mtime\":1768485628962,\"results\":\"603\",\"hashOfConfig\":\"491\"},{\"size\":898,\"mtime\":1768485628962,\"results\":\"604\",\"hashOfConfig\":\"491\"},{\"size\":150,\"mtime\":1768485628962,\"results\":\"605\",\"hashOfConfig\":\"491\"},{\"size\":773,\"mtime\":1768485628962,\"results\":\"606\",\"hashOfConfig\":\"496\"},{\"size\":589,\"mtime\":1768935766634,\"results\":\"607\",\"hashOfConfig\":\"491\"},{\"size\":211,\"mtime\":1768935766634,\"results\":\"608\",\"hashOfConfig\":\"491\"},{\"size\":155,\"mtime\":1768485628962,\"results\":\"609\",\"hashOfConfig\":\"491\"},{\"size\":683,\"mtime\":1768485628962,\"results\":\"610\",\"hashOfConfig\":\"491\"},{\"size\":127,\"mtime\":1768485628962,\"results\":\"611\",\"hashOfConfig\":\"491\"},{\"size\":20,\"mtime\":1768485628962,\"results\":\"612\",\"hashOfConfig\":\"491\"},{\"size\":20,\"mtime\":1768485628963,\"results\":\"613\",\"hashOfConfig\":\"496\"},{\"size\":630,\"mtime\":1768935766634,\"results\":\"614\",\"hashOfConfig\":\"491\"},{\"size\":73,\"mtime\":1768935766634,\"results\":\"615\",\"hashOfConfig\":\"496\"},{\"size\":98,\"mtime\":1769017480816,\"results\":\"616\",\"hashOfConfig\":\"491\"},{\"size\":106,\"mtime\":1769017481745,\"results\":\"617\",\"hashOfConfig\":\"491\"},{\"size\":130,\"mtime\":1768485628963,\"results\":\"618\",\"hashOfConfig\":\"491\"},{\"size\":3765,\"mtime\":1768485628963,\"results\":\"619\",\"hashOfConfig\":\"491\"},{\"size\":554,\"mtime\":1768485628963,\"results\":\"620\",\"hashOfConfig\":\"491\"},{\"size\":3432,\"mtime\":1768485628963,\"results\":\"621\",\"hashOfConfig\":\"491\"},{\"size\":2654,\"mtime\":1768485628963,\"results\":\"622\",\"hashOfConfig\":\"491\"},{\"size\":592,\"mtime\":1768485628964,\"results\":\"623\",\"hashOfConfig\":\"491\"},{\"size\":3107,\"mtime\":1769018727869,\"results\":\"624\",\"hashOfConfig\":\"491\"},{\"size\":3313,\"mtime\":1769020222179,\"results\":\"625\",\"hashOfConfig\":\"491\"},{\"size\":2914,\"mtime\":1768485628964,\"results\":\"626\",\"hashOfConfig\":\"491\"},{\"size\":7864,\"mtime\":1768935766636,\"results\":\"627\",\"hashOfConfig\":\"491\"},{\"size\":1007,\"mtime\":1768485628964,\"results\":\"628\",\"hashOfConfig\":\"491\"},{\"size\":2685,\"mtime\":1769112665825,\"results\":\"629\",\"hashOfConfig\":\"491\"},{\"size\":3323,\"mtime\":1768935766636,\"results\":\"630\",\"hashOfConfig\":\"491\"},{\"size\":375,\"mtime\":1768485628964,\"results\":\"631\",\"hashOfConfig\":\"491\"},{\"size\":939,\"mtime\":1768485628964,\"results\":\"632\",\"hashOfConfig\":\"491\"},{\"size\":2580,\"mtime\":1768485628964,\"results\":\"633\",\"hashOfConfig\":\"491\"},{\"size\":2833,\"mtime\":1769111694906,\"results\":\"634\",\"hashOfConfig\":\"491\"},{\"size\":500,\"mtime\":1768485628964,\"results\":\"635\",\"hashOfConfig\":\"491\"},{\"size\":494,\"mtime\":1768935766636,\"results\":\"636\",\"hashOfConfig\":\"491\"},{\"size\":2730,\"mtime\":1769018634698,\"results\":\"637\",\"hashOfConfig\":\"491\"},{\"size\":2885,\"mtime\":1768485628964,\"results\":\"638\",\"hashOfConfig\":\"491\"},{\"size\":2044,\"mtime\":1768485628964,\"results\":\"639\",\"hashOfConfig\":\"491\"},{\"size\":481,\"mtime\":1768935766636,\"results\":\"640\",\"hashOfConfig\":\"491\"},{\"size\":3117,\"mtime\":1768935766636,\"results\":\"641\",\"hashOfConfig\":\"491\"},{\"size\":3140,\"mtime\":1768485628964,\"results\":\"642\",\"hashOfConfig\":\"491\"},{\"size\":865,\"mtime\":1768485628964,\"results\":\"643\",\"hashOfConfig\":\"491\"},{\"size\":2133,\"mtime\":1768485628964,\"results\":\"644\",\"hashOfConfig\":\"491\"},{\"size\":9200,\"mtime\":1768868651078,\"results\":\"645\",\"hashOfConfig\":\"491\"},{\"size\":1242,\"mtime\":1768485628964,\"results\":\"646\",\"hashOfConfig\":\"491\"},{\"size\":1322,\"mtime\":1768485628964,\"results\":\"647\",\"hashOfConfig\":\"491\"},{\"size\":1146,\"mtime\":1768485628964,\"results\":\"648\",\"hashOfConfig\":\"491\"},{\"size\":885,\"mtime\":1769020222179,\"results\":\"649\",\"hashOfConfig\":\"491\"},{\"size\":565,\"mtime\":1768485628964,\"results\":\"650\",\"hashOfConfig\":\"491\"},{\"size\":359,\"mtime\":1768485628964,\"results\":\"651\",\"hashOfConfig\":\"491\"},{\"size\":5808,\"mtime\":1768935766636,\"results\":\"652\",\"hashOfConfig\":\"491\"},{\"size\":2048,\"mtime\":1768485628964,\"results\":\"653\",\"hashOfConfig\":\"491\"},{\"size\":879,\"mtime\":1768485628964,\"results\":\"654\",\"hashOfConfig\":\"491\"},{\"size\":3501,\"mtime\":1768485628964,\"results\":\"655\",\"hashOfConfig\":\"491\"},{\"size\":309,\"mtime\":1768485628964,\"results\":\"656\",\"hashOfConfig\":\"491\"},{\"size\":2793,\"mtime\":1768485628964,\"results\":\"657\",\"hashOfConfig\":\"491\"},{\"size\":1492,\"mtime\":1768485628964,\"results\":\"658\",\"hashOfConfig\":\"491\"},{\"size\":1436,\"mtime\":1768485628964,\"results\":\"659\",\"hashOfConfig\":\"491\"},{\"size\":613,\"mtime\":1768935766636,\"results\":\"660\",\"hashOfConfig\":\"491\"},{\"size\":3531,\"mtime\":1769111910945,\"results\":\"661\",\"hashOfConfig\":\"491\"},{\"size\":7854,\"mtime\":1769020222179,\"results\":\"662\",\"hashOfConfig\":\"491\"},{\"size\":3580,\"mtime\":1769018634698,\"results\":\"663\",\"hashOfConfig\":\"491\"},{\"size\":14692,\"mtime\":1769018634698,\"results\":\"664\",\"hashOfConfig\":\"491\"},{\"size\":4130,\"mtime\":1768935766637,\"results\":\"665\",\"hashOfConfig\":\"491\"},{\"size\":5798,\"mtime\":1768485628964,\"results\":\"666\",\"hashOfConfig\":\"491\"},{\"size\":1469,\"mtime\":1769018634698,\"results\":\"667\",\"hashOfConfig\":\"491\"},{\"size\":561,\"mtime\":1768485628964,\"results\":\"668\",\"hashOfConfig\":\"491\"},{\"size\":1617,\"mtime\":1768485628964,\"results\":\"669\",\"hashOfConfig\":\"491\"},{\"size\":2090,\"mtime\":1768485628964,\"results\":\"670\",\"hashOfConfig\":\"491\"},{\"size\":508,\"mtime\":1768485628964,\"results\":\"671\",\"hashOfConfig\":\"491\"},{\"size\":306,\"mtime\":1768485628964,\"results\":\"672\",\"hashOfConfig\":\"491\"},{\"size\":862,\"mtime\":1768485628964,\"results\":\"673\",\"hashOfConfig\":\"491\"},{\"size\":1561,\"mtime\":1768485628964,\"results\":\"674\",\"hashOfConfig\":\"491\"},{\"size\":288,\"mtime\":1768485628964,\"results\":\"675\",\"hashOfConfig\":\"491\"},{\"size\":573,\"mtime\":1768485628964,\"results\":\"676\",\"hashOfConfig\":\"491\"},{\"size\":1743,\"mtime\":1769018634698,\"results\":\"677\",\"hashOfConfig\":\"491\"},{\"size\":6134,\"mtime\":1768485628965,\"results\":\"678\",\"hashOfConfig\":\"491\"},{\"size\":1877,\"mtime\":1768485628965,\"results\":\"679\",\"hashOfConfig\":\"491\"},{\"size\":2489,\"mtime\":1768485628965,\"results\":\"680\",\"hashOfConfig\":\"491\"},{\"size\":286,\"mtime\":1768485628965,\"results\":\"681\",\"hashOfConfig\":\"491\"},{\"size\":739,\"mtime\":1768485628965,\"results\":\"682\",\"hashOfConfig\":\"491\"},{\"size\":674,\"mtime\":1768485628965,\"results\":\"683\",\"hashOfConfig\":\"491\"},{\"size\":1613,\"mtime\":1768485628965,\"results\":\"684\",\"hashOfConfig\":\"491\"},{\"size\":1251,\"mtime\":1768485628965,\"results\":\"685\",\"hashOfConfig\":\"491\"},{\"size\":1747,\"mtime\":1768485628965,\"results\":\"686\",\"hashOfConfig\":\"491\"},{\"size\":5347,\"mtime\":1768485628965,\"results\":\"687\",\"hashOfConfig\":\"491\"},{\"size\":2152,\"mtime\":1768485628965,\"results\":\"688\",\"hashOfConfig\":\"491\"},{\"size\":2094,\"mtime\":1768485628965,\"results\":\"689\",\"hashOfConfig\":\"491\"},{\"size\":126,\"mtime\":1768485628965,\"results\":\"690\",\"hashOfConfig\":\"491\"},{\"size\":2237,\"mtime\":1768485628965,\"results\":\"691\",\"hashOfConfig\":\"491\"},{\"size\":1368,\"mtime\":1768485628965,\"results\":\"692\",\"hashOfConfig\":\"491\"},{\"size\":250,\"mtime\":1768485628965,\"results\":\"693\",\"hashOfConfig\":\"491\"},{\"size\":633,\"mtime\":1768485628965,\"results\":\"694\",\"hashOfConfig\":\"491\"},{\"size\":4444,\"mtime\":1768485628965,\"results\":\"695\",\"hashOfConfig\":\"491\"},{\"size\":7333,\"mtime\":1768485628966,\"results\":\"696\",\"hashOfConfig\":\"491\"},{\"size\":5919,\"mtime\":1768485628966,\"results\":\"697\",\"hashOfConfig\":\"491\"},{\"size\":1061,\"mtime\":1768485628966,\"results\":\"698\",\"hashOfConfig\":\"491\"},{\"size\":1270,\"mtime\":1768485628966,\"results\":\"699\",\"hashOfConfig\":\"491\"},{\"size\":2311,\"mtime\":1768935766637,\"results\":\"700\",\"hashOfConfig\":\"491\"},{\"size\":12420,\"mtime\":1768485628966,\"results\":\"701\",\"hashOfConfig\":\"491\"},{\"size\":3209,\"mtime\":1768485628966,\"results\":\"702\",\"hashOfConfig\":\"491\"},{\"size\":492,\"mtime\":1768485628966,\"results\":\"703\",\"hashOfConfig\":\"491\"},{\"size\":742,\"mtime\":1768485628966,\"results\":\"704\",\"hashOfConfig\":\"491\"},{\"size\":373,\"mtime\":1768485628966,\"results\":\"705\",\"hashOfConfig\":\"491\"},{\"size\":179,\"mtime\":1768485628966,\"results\":\"706\",\"hashOfConfig\":\"491\"},{\"size\":2341,\"mtime\":1769020222179,\"results\":\"707\",\"hashOfConfig\":\"491\"},{\"size\":713,\"mtime\":1768485628966,\"results\":\"708\",\"hashOfConfig\":\"491\"},{\"size\":947,\"mtime\":1768485628966,\"results\":\"709\",\"hashOfConfig\":\"491\"},{\"size\":3441,\"mtime\":1768485628967,\"results\":\"710\",\"hashOfConfig\":\"491\"},{\"size\":1434,\"mtime\":1768485628967,\"results\":\"711\",\"hashOfConfig\":\"491\"},{\"size\":756,\"mtime\":1768485628967,\"results\":\"712\",\"hashOfConfig\":\"491\"},{\"size\":510,\"mtime\":1768485628967,\"results\":\"713\",\"hashOfConfig\":\"491\"},{\"size\":368,\"mtime\":1768485628967,\"results\":\"714\",\"hashOfConfig\":\"491\"},{\"size\":950,\"mtime\":1768485628967,\"results\":\"715\",\"hashOfConfig\":\"491\"},{\"size\":493,\"mtime\":1768935766637,\"results\":\"716\",\"hashOfConfig\":\"491\"},{\"size\":5386,\"mtime\":1768485628967,\"results\":\"717\",\"hashOfConfig\":\"491\"},{\"size\":2894,\"mtime\":1768485628967,\"results\":\"718\",\"hashOfConfig\":\"491\"},{\"size\":547,\"mtime\":1768485628967,\"results\":\"719\",\"hashOfConfig\":\"491\"},{\"size\":4383,\"mtime\":1768485628967,\"results\":\"720\",\"hashOfConfig\":\"491\"},{\"size\":1473,\"mtime\":1768935766637,\"results\":\"721\",\"hashOfConfig\":\"491\"},{\"size\":734,\"mtime\":1768485628967,\"results\":\"722\",\"hashOfConfig\":\"491\"},{\"size\":61,\"mtime\":1765879310418,\"results\":\"723\",\"hashOfConfig\":\"491\"},{\"size\":756,\"mtime\":1768485628967,\"results\":\"724\",\"hashOfConfig\":\"491\"},{\"size\":1737,\"mtime\":1768485628967,\"results\":\"725\",\"hashOfConfig\":\"491\"},{\"size\":1762,\"mtime\":1768485628967,\"results\":\"726\",\"hashOfConfig\":\"491\"},{\"size\":249,\"mtime\":1762360155096,\"results\":\"727\",\"hashOfConfig\":\"491\"},{\"size\":4758,\"mtime\":1768485628967,\"results\":\"728\",\"hashOfConfig\":\"491\"},{\"size\":404,\"mtime\":1768485628967,\"results\":\"729\",\"hashOfConfig\":\"491\"},{\"size\":1414,\"mtime\":1769020222179,\"results\":\"730\",\"hashOfConfig\":\"491\"},{\"size\":250,\"mtime\":1768485628967,\"results\":\"731\",\"hashOfConfig\":\"491\"},{\"size\":2618,\"mtime\":1768485628967,\"results\":\"732\",\"hashOfConfig\":\"491\"},{\"size\":1299,\"mtime\":1768485628967,\"results\":\"733\",\"hashOfConfig\":\"491\"},{\"size\":4485,\"mtime\":1768485628967,\"results\":\"734\",\"hashOfConfig\":\"491\"},{\"size\":3179,\"mtime\":1768935766637,\"results\":\"735\",\"hashOfConfig\":\"491\"},{\"size\":3116,\"mtime\":1769020222179,\"results\":\"736\",\"hashOfConfig\":\"491\"},{\"size\":969,\"mtime\":1769020222179,\"results\":\"737\",\"hashOfConfig\":\"491\"},{\"size\":1997,\"mtime\":1769020222180,\"results\":\"738\",\"hashOfConfig\":\"491\"},{\"size\":3442,\"mtime\":1768485628967,\"results\":\"739\",\"hashOfConfig\":\"491\"},{\"size\":879,\"mtime\":1767619337864,\"results\":\"740\",\"hashOfConfig\":\"496\"},{\"size\":4704,\"mtime\":1768485628967,\"results\":\"741\",\"hashOfConfig\":\"491\"},{\"size\":2733,\"mtime\":1768485628967,\"results\":\"742\",\"hashOfConfig\":\"491\"},{\"size\":922,\"mtime\":1768485628968,\"results\":\"743\",\"hashOfConfig\":\"491\"},{\"size\":10545,\"mtime\":1768485628968,\"results\":\"744\",\"hashOfConfig\":\"491\"},{\"size\":440,\"mtime\":1765879310419,\"results\":\"745\",\"hashOfConfig\":\"491\"},{\"size\":9729,\"mtime\":1768485628968,\"results\":\"746\",\"hashOfConfig\":\"491\"},{\"size\":34941,\"mtime\":1767619337864,\"results\":\"747\",\"hashOfConfig\":\"491\"},{\"size\":2078,\"mtime\":1768485628968,\"results\":\"748\",\"hashOfConfig\":\"491\"},{\"size\":952,\"mtime\":1769020222180,\"results\":\"749\",\"hashOfConfig\":\"491\"},{\"size\":1261,\"mtime\":1769020222180,\"results\":\"750\",\"hashOfConfig\":\"491\"},{\"size\":5281,\"mtime\":1768485628968,\"results\":\"751\",\"hashOfConfig\":\"491\"},{\"size\":713,\"mtime\":1768485628968,\"results\":\"752\",\"hashOfConfig\":\"491\"},{\"size\":246,\"mtime\":1768485628968,\"results\":\"753\",\"hashOfConfig\":\"491\"},{\"size\":1626,\"mtime\":1768485628968,\"results\":\"754\",\"hashOfConfig\":\"491\"},{\"size\":2382,\"mtime\":1768485628968,\"results\":\"755\",\"hashOfConfig\":\"491\"},{\"size\":249,\"mtime\":1768485628968,\"results\":\"756\",\"hashOfConfig\":\"491\"},{\"size\":205,\"mtime\":1768485628968,\"results\":\"757\",\"hashOfConfig\":\"491\"},{\"size\":227,\"mtime\":1768485628968,\"results\":\"758\",\"hashOfConfig\":\"491\"},{\"size\":700,\"mtime\":1768485628968,\"results\":\"759\",\"hashOfConfig\":\"491\"},{\"size\":6279,\"mtime\":1768485628968,\"results\":\"760\",\"hashOfConfig\":\"491\"},{\"size\":138,\"mtime\":1768485628968,\"results\":\"761\",\"hashOfConfig\":\"491\"},{\"size\":224,\"mtime\":1768485628968,\"results\":\"762\",\"hashOfConfig\":\"491\"},{\"size\":5043,\"mtime\":1768485628968,\"results\":\"763\",\"hashOfConfig\":\"491\"},{\"size\":899,\"mtime\":1768935766637,\"results\":\"764\",\"hashOfConfig\":\"491\"},{\"size\":1071,\"mtime\":1768935766637,\"results\":\"765\",\"hashOfConfig\":\"491\"},{\"size\":2082,\"mtime\":1768485628968,\"results\":\"766\",\"hashOfConfig\":\"491\"},{\"size\":3999,\"mtime\":1768485628968,\"results\":\"767\",\"hashOfConfig\":\"491\"},{\"size\":1103,\"mtime\":1768485628968,\"results\":\"768\",\"hashOfConfig\":\"491\"},{\"size\":560,\"mtime\":1768485628968,\"results\":\"769\",\"hashOfConfig\":\"491\"},{\"size\":1517,\"mtime\":1769020222180,\"results\":\"770\",\"hashOfConfig\":\"491\"},{\"size\":599,\"mtime\":1769020222180,\"results\":\"771\",\"hashOfConfig\":\"491\"},{\"size\":1270,\"mtime\":1769020222180,\"results\":\"772\",\"hashOfConfig\":\"491\"},{\"size\":240,\"mtime\":1768485628968,\"results\":\"773\",\"hashOfConfig\":\"491\"},{\"size\":237,\"mtime\":1768485628968,\"results\":\"774\",\"hashOfConfig\":\"491\"},{\"size\":565,\"mtime\":1768485628968,\"results\":\"775\",\"hashOfConfig\":\"491\"},{\"size\":155,\"mtime\":1768485628969,\"results\":\"776\",\"hashOfConfig\":\"491\"},{\"size\":373,\"mtime\":1768485628969,\"results\":\"777\",\"hashOfConfig\":\"491\"},{\"size\":1650,\"mtime\":1768485628969,\"results\":\"778\",\"hashOfConfig\":\"491\"},{\"size\":2883,\"mtime\":1768935766637,\"results\":\"779\",\"hashOfConfig\":\"491\"},{\"size\":702,\"mtime\":1768485628969,\"results\":\"780\",\"hashOfConfig\":\"491\"},{\"size\":1121,\"mtime\":1768935766638,\"results\":\"781\",\"hashOfConfig\":\"491\"},{\"size\":1127,\"mtime\":1768935766638,\"results\":\"782\",\"hashOfConfig\":\"491\"},{\"size\":4585,\"mtime\":1768485628969,\"results\":\"783\",\"hashOfConfig\":\"491\"},{\"size\":14440,\"mtime\":1769100988355,\"results\":\"784\",\"hashOfConfig\":\"491\"},{\"size\":473,\"mtime\":1768485628969,\"results\":\"785\",\"hashOfConfig\":\"491\"},{\"size\":3264,\"mtime\":1768485628969,\"results\":\"786\",\"hashOfConfig\":\"491\"},{\"size\":2037,\"mtime\":1768485628969,\"results\":\"787\",\"hashOfConfig\":\"491\"},{\"size\":171,\"mtime\":1768485628969,\"results\":\"788\",\"hashOfConfig\":\"491\"},{\"size\":488,\"mtime\":1768485628969,\"results\":\"789\",\"hashOfConfig\":\"491\"},{\"size\":6267,\"mtime\":1768935766638,\"results\":\"790\",\"hashOfConfig\":\"491\"},{\"size\":5567,\"mtime\":1768485628969,\"results\":\"791\",\"hashOfConfig\":\"491\"},{\"size\":3350,\"mtime\":1768485628969,\"results\":\"792\",\"hashOfConfig\":\"491\"},{\"size\":110,\"mtime\":1768485628969,\"results\":\"793\",\"hashOfConfig\":\"491\"},{\"size\":81,\"mtime\":1768485628969,\"results\":\"794\",\"hashOfConfig\":\"491\"},{\"size\":218,\"mtime\":1768485628969,\"results\":\"795\",\"hashOfConfig\":\"491\"},{\"size\":52,\"mtime\":1768485628969,\"results\":\"796\",\"hashOfConfig\":\"491\"},{\"size\":54,\"mtime\":1768485628969,\"results\":\"797\",\"hashOfConfig\":\"491\"},{\"size\":7922,\"mtime\":1768485628969,\"results\":\"798\",\"hashOfConfig\":\"491\"},{\"size\":10407,\"mtime\":1768485628969,\"results\":\"799\",\"hashOfConfig\":\"491\"},{\"size\":1098,\"mtime\":1768485628969,\"results\":\"800\",\"hashOfConfig\":\"491\"},{\"size\":555,\"mtime\":1768485628969,\"results\":\"801\",\"hashOfConfig\":\"491\"},{\"size\":0,\"mtime\":1765879310420,\"results\":\"802\",\"hashOfConfig\":\"491\"},{\"size\":5313,\"mtime\":1768935766638,\"results\":\"803\",\"hashOfConfig\":\"491\"},{\"size\":442,\"mtime\":1768485628969,\"results\":\"804\",\"hashOfConfig\":\"491\"},{\"size\":2114,\"mtime\":1768485628969,\"results\":\"805\",\"hashOfConfig\":\"491\"},{\"size\":337,\"mtime\":1768485628969,\"results\":\"806\",\"hashOfConfig\":\"491\"},{\"size\":125,\"mtime\":1768485628969,\"results\":\"807\",\"hashOfConfig\":\"491\"},{\"size\":172,\"mtime\":1768485628969,\"results\":\"808\",\"hashOfConfig\":\"491\"},{\"size\":2804,\"mtime\":1768485628969,\"results\":\"809\",\"hashOfConfig\":\"491\"},{\"size\":860,\"mtime\":1768485628969,\"results\":\"810\",\"hashOfConfig\":\"491\"},{\"size\":3302,\"mtime\":1768485628969,\"results\":\"811\",\"hashOfConfig\":\"491\"},{\"size\":930,\"mtime\":1768485628969,\"results\":\"812\",\"hashOfConfig\":\"491\"},{\"size\":214,\"mtime\":1768485628969,\"results\":\"813\",\"hashOfConfig\":\"491\"},{\"size\":5542,\"mtime\":1768485628969,\"results\":\"814\",\"hashOfConfig\":\"491\"},{\"size\":1690,\"mtime\":1768485628969,\"results\":\"815\",\"hashOfConfig\":\"491\"},{\"size\":2237,\"mtime\":1768485628970,\"results\":\"816\",\"hashOfConfig\":\"491\"},{\"size\":2613,\"mtime\":1768485628970,\"results\":\"817\",\"hashOfConfig\":\"491\"},{\"size\":410,\"mtime\":1768485628970,\"results\":\"818\",\"hashOfConfig\":\"491\"},{\"size\":2446,\"mtime\":1768485628970,\"results\":\"819\",\"hashOfConfig\":\"491\"},{\"size\":404,\"mtime\":1769020222180,\"results\":\"820\",\"hashOfConfig\":\"496\"},{\"size\":9214,\"mtime\":1768935766638,\"results\":\"821\",\"hashOfConfig\":\"496\"},{\"size\":179,\"mtime\":1768485628970,\"results\":\"822\",\"hashOfConfig\":\"496\"},{\"size\":846,\"mtime\":1768485628970,\"results\":\"823\",\"hashOfConfig\":\"491\"},{\"size\":1522,\"mtime\":1768485628970,\"results\":\"824\",\"hashOfConfig\":\"491\"},{\"size\":65,\"mtime\":1768485628970,\"results\":\"825\",\"hashOfConfig\":\"491\"},{\"size\":52,\"mtime\":1768485628970,\"results\":\"826\",\"hashOfConfig\":\"491\"},{\"size\":58,\"mtime\":1768485628970,\"results\":\"827\",\"hashOfConfig\":\"491\"},{\"size\":212,\"mtime\":1768485628970,\"results\":\"828\",\"hashOfConfig\":\"491\"},{\"size\":197,\"mtime\":1768485628971,\"results\":\"829\",\"hashOfConfig\":\"491\"},{\"size\":463,\"mtime\":1768485628971,\"results\":\"830\",\"hashOfConfig\":\"491\"},{\"size\":294,\"mtime\":1769020222180,\"results\":\"831\",\"hashOfConfig\":\"491\"},{\"size\":126,\"mtime\":1768485628971,\"results\":\"832\",\"hashOfConfig\":\"491\"},{\"size\":49,\"mtime\":1768485628971,\"results\":\"833\",\"hashOfConfig\":\"491\"},{\"size\":477,\"mtime\":1768485628971,\"results\":\"834\",\"hashOfConfig\":\"491\"},{\"size\":305,\"mtime\":1768485628971,\"results\":\"835\",\"hashOfConfig\":\"491\"},{\"size\":182,\"mtime\":1768485628971,\"results\":\"836\",\"hashOfConfig\":\"491\"},{\"size\":591,\"mtime\":1768485628971,\"results\":\"837\",\"hashOfConfig\":\"491\"},{\"size\":163,\"mtime\":1768485628971,\"results\":\"838\",\"hashOfConfig\":\"491\"},{\"size\":433,\"mtime\":1768485628971,\"results\":\"839\",\"hashOfConfig\":\"491\"},{\"size\":156,\"mtime\":1768485628971,\"results\":\"840\",\"hashOfConfig\":\"491\"},{\"size\":259,\"mtime\":1768485628971,\"results\":\"841\",\"hashOfConfig\":\"491\"},{\"size\":563,\"mtime\":1768485628971,\"results\":\"842\",\"hashOfConfig\":\"491\"},{\"size\":5096,\"mtime\":1768485628971,\"results\":\"843\",\"hashOfConfig\":\"491\"},{\"size\":3415,\"mtime\":1768485628971,\"results\":\"844\",\"hashOfConfig\":\"491\"},{\"size\":679,\"mtime\":1768485628971,\"results\":\"845\",\"hashOfConfig\":\"491\"},{\"size\":643,\"mtime\":1769018634698,\"results\":\"846\",\"hashOfConfig\":\"491\"},{\"size\":10091,\"mtime\":1769018634698,\"results\":\"847\",\"hashOfConfig\":\"491\"},{\"size\":3511,\"mtime\":1768485628971,\"results\":\"848\",\"hashOfConfig\":\"491\"},{\"size\":2006,\"mtime\":1766053453788,\"results\":\"849\",\"hashOfConfig\":\"491\"},{\"size\":3555,\"mtime\":1768935766638,\"results\":\"850\",\"hashOfConfig\":\"491\"},{\"size\":90,\"mtime\":1768485628971,\"results\":\"851\",\"hashOfConfig\":\"491\"},{\"size\":500,\"mtime\":1769020222180,\"results\":\"852\",\"hashOfConfig\":\"491\"},{\"size\":846,\"mtime\":1768935766638,\"results\":\"853\",\"hashOfConfig\":\"491\"},{\"size\":1928,\"mtime\":1768485628971,\"results\":\"854\",\"hashOfConfig\":\"491\"},{\"size\":1276,\"mtime\":1769018634698,\"results\":\"855\",\"hashOfConfig\":\"491\"},{\"size\":650,\"mtime\":1769018634698,\"results\":\"856\",\"hashOfConfig\":\"491\"},{\"size\":265,\"mtime\":1768485628971,\"results\":\"857\",\"hashOfConfig\":\"491\"},{\"size\":2256,\"mtime\":1768485628971,\"results\":\"858\",\"hashOfConfig\":\"491\"},{\"size\":38164,\"mtime\":1765879310420,\"results\":\"859\",\"hashOfConfig\":\"491\"},{\"size\":1031,\"mtime\":1768485628971,\"results\":\"860\",\"hashOfConfig\":\"491\"},{\"size\":391,\"mtime\":1768485628971,\"results\":\"861\",\"hashOfConfig\":\"491\"},{\"size\":371,\"mtime\":1768485628971,\"results\":\"862\",\"hashOfConfig\":\"491\"},{\"size\":2195,\"mtime\":1768485628971,\"results\":\"863\",\"hashOfConfig\":\"491\"},{\"size\":1003,\"mtime\":1768485628971,\"results\":\"864\",\"hashOfConfig\":\"491\"},{\"size\":236,\"mtime\":1768485628971,\"results\":\"865\",\"hashOfConfig\":\"491\"},{\"size\":1121,\"mtime\":1768485628971,\"results\":\"866\",\"hashOfConfig\":\"491\"},{\"size\":111,\"mtime\":1768485628971,\"results\":\"867\",\"hashOfConfig\":\"491\"},{\"size\":1245,\"mtime\":1768485628971,\"results\":\"868\",\"hashOfConfig\":\"491\"},{\"size\":702,\"mtime\":1762360155102,\"results\":\"869\",\"hashOfConfig\":\"491\"},{\"size\":43,\"mtime\":1768485628971,\"results\":\"870\",\"hashOfConfig\":\"491\"},{\"size\":4022,\"mtime\":1768485628971,\"results\":\"871\",\"hashOfConfig\":\"491\"},{\"size\":1553,\"mtime\":1768485628971,\"results\":\"872\",\"hashOfConfig\":\"491\"},{\"size\":2138,\"mtime\":1768485628971,\"results\":\"873\",\"hashOfConfig\":\"491\"},{\"size\":1911,\"mtime\":1768485628971,\"results\":\"874\",\"hashOfConfig\":\"491\"},{\"size\":1108,\"mtime\":1768935766638,\"results\":\"875\",\"hashOfConfig\":\"491\"},{\"size\":691,\"mtime\":1768485628971,\"results\":\"876\",\"hashOfConfig\":\"491\"},{\"size\":128,\"mtime\":1768485628971,\"results\":\"877\",\"hashOfConfig\":\"491\"},{\"size\":2895,\"mtime\":1768935766638,\"results\":\"878\",\"hashOfConfig\":\"491\"},{\"size\":288,\"mtime\":1768485628971,\"results\":\"879\",\"hashOfConfig\":\"491\"},{\"size\":63,\"mtime\":1768485628971,\"results\":\"880\",\"hashOfConfig\":\"491\"},{\"size\":4064,\"mtime\":1768935766639,\"results\":\"881\",\"hashOfConfig\":\"491\"},{\"size\":23,\"mtime\":1768485628971,\"results\":\"882\",\"hashOfConfig\":\"496\"},{\"size\":23,\"mtime\":1768485628972,\"results\":\"883\",\"hashOfConfig\":\"491\"},{\"size\":120,\"mtime\":1768485628972,\"results\":\"884\",\"hashOfConfig\":\"491\"},{\"size\":240,\"mtime\":1768485628972,\"results\":\"885\",\"hashOfConfig\":\"491\"},{\"size\":299,\"mtime\":1768485628972,\"results\":\"886\",\"hashOfConfig\":\"491\"},{\"size\":59,\"mtime\":1768485628972,\"results\":\"887\",\"hashOfConfig\":\"491\"},{\"size\":131,\"mtime\":1768485628972,\"results\":\"888\",\"hashOfConfig\":\"491\"},{\"size\":120,\"mtime\":1768485628972,\"results\":\"889\",\"hashOfConfig\":\"491\"},{\"size\":234,\"mtime\":1768485628972,\"results\":\"890\",\"hashOfConfig\":\"491\"},{\"size\":542,\"mtime\":1768485628972,\"results\":\"891\",\"hashOfConfig\":\"491\"},{\"size\":210,\"mtime\":1768485628972,\"results\":\"892\",\"hashOfConfig\":\"491\"},{\"size\":151,\"mtime\":1768485628972,\"results\":\"893\",\"hashOfConfig\":\"491\"},{\"size\":184,\"mtime\":1768485628972,\"results\":\"894\",\"hashOfConfig\":\"491\"},{\"size\":498,\"mtime\":1768485628972,\"results\":\"895\",\"hashOfConfig\":\"491\"},{\"size\":49,\"mtime\":1768485628972,\"results\":\"896\",\"hashOfConfig\":\"491\"},{\"size\":163,\"mtime\":1768485628972,\"results\":\"897\",\"hashOfConfig\":\"491\"},{\"size\":82,\"mtime\":1768485628972,\"results\":\"898\",\"hashOfConfig\":\"491\"},{\"size\":875,\"mtime\":1768935766639,\"results\":\"899\",\"hashOfConfig\":\"491\"},{\"size\":32,\"mtime\":1768485628972,\"results\":\"900\",\"hashOfConfig\":\"491\"},{\"size\":28,\"mtime\":1768485628972,\"results\":\"901\",\"hashOfConfig\":\"491\"},{\"size\":195,\"mtime\":1768485628972,\"results\":\"902\",\"hashOfConfig\":\"491\"},{\"size\":434,\"mtime\":1768485628972,\"results\":\"903\",\"hashOfConfig\":\"491\"},{\"size\":390,\"mtime\":1768485628972,\"results\":\"904\",\"hashOfConfig\":\"491\"},{\"size\":48,\"mtime\":1768485628972,\"results\":\"905\",\"hashOfConfig\":\"491\"},{\"size\":137,\"mtime\":1768485628972,\"results\":\"906\",\"hashOfConfig\":\"491\"},{\"size\":796,\"mtime\":1768485628972,\"results\":\"907\",\"hashOfConfig\":\"491\"},{\"size\":683,\"mtime\":1768485628972,\"results\":\"908\",\"hashOfConfig\":\"491\"},{\"size\":141,\"mtime\":1768485628972,\"results\":\"909\",\"hashOfConfig\":\"491\"},{\"size\":238,\"mtime\":1768485628972,\"results\":\"910\",\"hashOfConfig\":\"491\"},{\"size\":363,\"mtime\":1768485628972,\"results\":\"911\",\"hashOfConfig\":\"491\"},{\"size\":32,\"mtime\":1768485628972,\"results\":\"912\",\"hashOfConfig\":\"491\"},{\"size\":33,\"mtime\":1768485628972,\"results\":\"913\",\"hashOfConfig\":\"491\"},{\"size\":114,\"mtime\":1768485628972,\"results\":\"914\",\"hashOfConfig\":\"491\"},{\"size\":809,\"mtime\":1768485628972,\"results\":\"915\",\"hashOfConfig\":\"491\"},{\"size\":335,\"mtime\":1768485628972,\"results\":\"916\",\"hashOfConfig\":\"491\"},{\"size\":975,\"mtime\":1768485628972,\"results\":\"917\",\"hashOfConfig\":\"491\"},{\"size\":273,\"mtime\":1768485628972,\"results\":\"918\",\"hashOfConfig\":\"491\"},{\"size\":52,\"mtime\":1768485628972,\"results\":\"919\",\"hashOfConfig\":\"491\"},{\"size\":82,\"mtime\":1768485628972,\"results\":\"920\",\"hashOfConfig\":\"491\"},{\"size\":511,\"mtime\":1768485628972,\"results\":\"921\",\"hashOfConfig\":\"491\"},{\"size\":1967,\"mtime\":1768485628972,\"results\":\"922\",\"hashOfConfig\":\"491\"},{\"size\":447,\"mtime\":1768485628972,\"results\":\"923\",\"hashOfConfig\":\"491\"},{\"size\":1208,\"mtime\":1768485628972,\"results\":\"924\",\"hashOfConfig\":\"491\"},{\"size\":252,\"mtime\":1768485628972,\"results\":\"925\",\"hashOfConfig\":\"491\"},{\"size\":138,\"mtime\":1768485628972,\"results\":\"926\",\"hashOfConfig\":\"491\"},{\"size\":104,\"mtime\":1768485628972,\"results\":\"927\",\"hashOfConfig\":\"491\"},{\"size\":350,\"mtime\":1768485628972,\"results\":\"928\",\"hashOfConfig\":\"491\"},{\"size\":333,\"mtime\":1768485628972,\"results\":\"929\",\"hashOfConfig\":\"491\"},{\"size\":334,\"mtime\":1768485628972,\"results\":\"930\",\"hashOfConfig\":\"491\"},{\"size\":382,\"mtime\":1768485628972,\"results\":\"931\",\"hashOfConfig\":\"491\"},{\"size\":299,\"mtime\":1768485628972,\"results\":\"932\",\"hashOfConfig\":\"491\"},{\"size\":276,\"mtime\":1768485628973,\"results\":\"933\",\"hashOfConfig\":\"491\"},{\"size\":231,\"mtime\":1768485628973,\"results\":\"934\",\"hashOfConfig\":\"491\"},{\"size\":452,\"mtime\":1768485628973,\"results\":\"935\",\"hashOfConfig\":\"491\"},{\"size\":41,\"mtime\":1768485628973,\"results\":\"936\",\"hashOfConfig\":\"491\"},{\"size\":39,\"mtime\":1768485628973,\"results\":\"937\",\"hashOfConfig\":\"491\"},{\"size\":35,\"mtime\":1768485628973,\"results\":\"938\",\"hashOfConfig\":\"491\"},{\"size\":45,\"mtime\":1762360155104,\"results\":\"939\",\"hashOfConfig\":\"491\"},{\"size\":236,\"mtime\":1768485628971,\"results\":\"940\",\"hashOfConfig\":\"491\"},{\"size\":130,\"mtime\":1769111988400,\"results\":\"941\",\"hashOfConfig\":\"491\"},{\"size\":2897,\"mtime\":1768485628973,\"results\":\"942\",\"hashOfConfig\":\"491\"},{\"size\":135,\"mtime\":1768928617550,\"results\":\"943\",\"hashOfConfig\":\"491\"},{\"size\":81,\"mtime\":1768485628973,\"results\":\"944\",\"hashOfConfig\":\"491\"},{\"size\":151,\"mtime\":1768485628973,\"results\":\"945\",\"hashOfConfig\":\"496\"},{\"size\":3012,\"mtime\":1768485628973,\"results\":\"946\",\"hashOfConfig\":\"491\"},{\"size\":3973,\"mtime\":1768485628973,\"results\":\"947\",\"hashOfConfig\":\"491\"},{\"size\":911,\"mtime\":1768485628973,\"results\":\"948\",\"hashOfConfig\":\"491\"},{\"size\":1584,\"mtime\":1768485628973,\"results\":\"949\",\"hashOfConfig\":\"491\"},{\"size\":2452,\"mtime\":1768485628973,\"results\":\"950\",\"hashOfConfig\":\"491\"},{\"size\":1024,\"mtime\":1768485628973,\"results\":\"951\",\"hashOfConfig\":\"491\"},{\"size\":7298,\"mtime\":1768485628973,\"results\":\"952\",\"hashOfConfig\":\"491\"},{\"size\":2424,\"mtime\":1768935766639,\"results\":\"953\",\"hashOfConfig\":\"491\"},{\"size\":1427,\"mtime\":1768485628973,\"results\":\"954\",\"hashOfConfig\":\"491\"},{\"size\":555,\"mtime\":1768485628973,\"results\":\"955\",\"hashOfConfig\":\"491\"},{\"size\":483,\"mtime\":1768485628973,\"results\":\"956\",\"hashOfConfig\":\"491\"},{\"size\":18122,\"mtime\":1768485628973,\"results\":\"957\",\"hashOfConfig\":\"491\"},{\"size\":1207,\"mtime\":1768485628973,\"results\":\"958\",\"hashOfConfig\":\"491\"},{\"size\":515,\"mtime\":1768485628973,\"results\":\"959\",\"hashOfConfig\":\"491\"},{\"size\":23391,\"mtime\":1769112905095,\"results\":\"960\",\"hashOfConfig\":\"491\"},{\"size\":1967,\"mtime\":1768485628973,\"results\":\"961\",\"hashOfConfig\":\"491\"},{\"size\":2728,\"mtime\":1768485628973,\"results\":\"962\",\"hashOfConfig\":\"491\"},{\"size\":1688,\"mtime\":1768485628973,\"results\":\"963\",\"hashOfConfig\":\"491\"},{\"size\":317,\"mtime\":1768485628973,\"results\":\"964\",\"hashOfConfig\":\"491\"},{\"size\":316,\"mtime\":1768485628973,\"results\":\"965\",\"hashOfConfig\":\"491\"},{\"filePath\":\"966\",\"messages\":\"967\",\"suppressedMessages\":\"968\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},\"17lpsoa\",{\"filePath\":\"969\",\"messages\":\"970\",\"suppressedMessages\":\"971\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"972\",\"messages\":\"973\",\"suppressedMessages\":\"974\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"975\",\"messages\":\"976\",\"suppressedMessages\":\"977\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"978\",\"messages\":\"979\",\"suppressedMessages\":\"980\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"981\",\"messages\":\"982\",\"suppressedMessages\":\"983\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"984\",\"messages\":\"985\",\"suppressedMessages\":\"986\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"987\",\"messages\":\"988\",\"suppressedMessages\":\"989\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},\"1l1toe8\",{\"filePath\":\"990\",\"messages\":\"991\",\"suppressedMessages\":\"992\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"993\",\"messages\":\"994\",\"suppressedMessages\":\"995\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"996\",\"messages\":\"997\",\"suppressedMessages\":\"998\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"999\",\"messages\":\"1000\",\"suppressedMessages\":\"1001\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},\"pc2r9k\",{\"filePath\":\"1002\",\"messages\":\"1003\",\"suppressedMessages\":\"1004\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1005\",\"messages\":\"1006\",\"suppressedMessages\":\"1007\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1008\",\"messages\":\"1009\",\"suppressedMessages\":\"1010\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1011\",\"messages\":\"1012\",\"suppressedMessages\":\"1013\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1014\",\"messages\":\"1015\",\"suppressedMessages\":\"1016\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1017\",\"messages\":\"1018\",\"suppressedMessages\":\"1019\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1020\",\"messages\":\"1021\",\"suppressedMessages\":\"1022\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1023\",\"messages\":\"1024\",\"suppressedMessages\":\"1025\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1026\",\"messages\":\"1027\",\"suppressedMessages\":\"1028\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1029\",\"messages\":\"1030\",\"suppressedMessages\":\"1031\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1032\",\"messages\":\"1033\",\"suppressedMessages\":\"1034\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1035\",\"messages\":\"1036\",\"suppressedMessages\":\"1037\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1038\",\"messages\":\"1039\",\"suppressedMessages\":\"1040\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1041\",\"messages\":\"1042\",\"suppressedMessages\":\"1043\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1044\",\"messages\":\"1045\",\"suppressedMessages\":\"1046\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1047\",\"messages\":\"1048\",\"suppressedMessages\":\"1049\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1050\",\"messages\":\"1051\",\"suppressedMessages\":\"1052\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1053\",\"messages\":\"1054\",\"suppressedMessages\":\"1055\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1056\",\"messages\":\"1057\",\"suppressedMessages\":\"1058\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1059\",\"messages\":\"1060\",\"suppressedMessages\":\"1061\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1062\",\"messages\":\"1063\",\"suppressedMessages\":\"1064\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1065\",\"messages\":\"1066\",\"suppressedMessages\":\"1067\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1068\",\"messages\":\"1069\",\"suppressedMessages\":\"1070\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1071\",\"messages\":\"1072\",\"suppressedMessages\":\"1073\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1074\",\"messages\":\"1075\",\"suppressedMessages\":\"1076\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1077\",\"messages\":\"1078\",\"suppressedMessages\":\"1079\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1080\",\"messages\":\"1081\",\"suppressedMessages\":\"1082\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1083\",\"messages\":\"1084\",\"suppressedMessages\":\"1085\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1086\",\"messages\":\"1087\",\"suppressedMessages\":\"1088\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1089\",\"messages\":\"1090\",\"suppressedMessages\":\"1091\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1092\",\"messages\":\"1093\",\"suppressedMessages\":\"1094\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1095\",\"messages\":\"1096\",\"suppressedMessages\":\"1097\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1098\",\"messages\":\"1099\",\"suppressedMessages\":\"1100\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1101\",\"messages\":\"1102\",\"suppressedMessages\":\"1103\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1104\",\"messages\":\"1105\",\"suppressedMessages\":\"1106\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1107\",\"messages\":\"1108\",\"suppressedMessages\":\"1109\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1110\",\"messages\":\"1111\",\"suppressedMessages\":\"1112\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1113\",\"messages\":\"1114\",\"suppressedMessages\":\"1115\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1116\",\"messages\":\"1117\",\"suppressedMessages\":\"1118\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1119\",\"messages\":\"1120\",\"suppressedMessages\":\"1121\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1122\",\"messages\":\"1123\",\"suppressedMessages\":\"1124\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1125\",\"messages\":\"1126\",\"suppressedMessages\":\"1127\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1128\",\"messages\":\"1129\",\"suppressedMessages\":\"1130\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1131\",\"messages\":\"1132\",\"suppressedMessages\":\"1133\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1134\",\"messages\":\"1135\",\"suppressedMessages\":\"1136\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1137\",\"messages\":\"1138\",\"suppressedMessages\":\"1139\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1140\",\"messages\":\"1141\",\"suppressedMessages\":\"1142\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1143\",\"messages\":\"1144\",\"suppressedMessages\":\"1145\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1146\",\"messages\":\"1147\",\"suppressedMessages\":\"1148\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1149\",\"messages\":\"1150\",\"suppressedMessages\":\"1151\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1152\",\"messages\":\"1153\",\"suppressedMessages\":\"1154\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1155\",\"messages\":\"1156\",\"suppressedMessages\":\"1157\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1158\",\"messages\":\"1159\",\"suppressedMessages\":\"1160\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1161\",\"messages\":\"1162\",\"suppressedMessages\":\"1163\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1164\",\"messages\":\"1165\",\"suppressedMessages\":\"1166\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1167\",\"messages\":\"1168\",\"suppressedMessages\":\"1169\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1170\",\"messages\":\"1171\",\"suppressedMessages\":\"1172\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1173\",\"messages\":\"1174\",\"suppressedMessages\":\"1175\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1176\",\"messages\":\"1177\",\"suppressedMessages\":\"1178\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1179\",\"messages\":\"1180\",\"suppressedMessages\":\"1181\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1182\",\"messages\":\"1183\",\"suppressedMessages\":\"1184\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1185\",\"messages\":\"1186\",\"suppressedMessages\":\"1187\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1188\",\"messages\":\"1189\",\"suppressedMessages\":\"1190\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1191\",\"messages\":\"1192\",\"suppressedMessages\":\"1193\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1194\",\"messages\":\"1195\",\"suppressedMessages\":\"1196\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1197\",\"messages\":\"1198\",\"suppressedMessages\":\"1199\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1200\",\"messages\":\"1201\",\"suppressedMessages\":\"1202\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1203\",\"messages\":\"1204\",\"suppressedMessages\":\"1205\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1206\",\"messages\":\"1207\",\"suppressedMessages\":\"1208\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1209\",\"messages\":\"1210\",\"suppressedMessages\":\"1211\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1212\",\"messages\":\"1213\",\"suppressedMessages\":\"1214\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1215\",\"messages\":\"1216\",\"suppressedMessages\":\"1217\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1218\",\"messages\":\"1219\",\"suppressedMessages\":\"1220\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1221\",\"messages\":\"1222\",\"suppressedMessages\":\"1223\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1224\",\"messages\":\"1225\",\"suppressedMessages\":\"1226\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1227\",\"messages\":\"1228\",\"suppressedMessages\":\"1229\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1230\",\"messages\":\"1231\",\"suppressedMessages\":\"1232\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1233\",\"messages\":\"1234\",\"suppressedMessages\":\"1235\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1236\",\"messages\":\"1237\",\"suppressedMessages\":\"1238\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1239\",\"messages\":\"1240\",\"suppressedMessages\":\"1241\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1242\",\"messages\":\"1243\",\"suppressedMessages\":\"1244\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1245\",\"messages\":\"1246\",\"suppressedMessages\":\"1247\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1248\",\"messages\":\"1249\",\"suppressedMessages\":\"1250\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1251\",\"messages\":\"1252\",\"suppressedMessages\":\"1253\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1254\",\"messages\":\"1255\",\"suppressedMessages\":\"1256\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1257\",\"messages\":\"1258\",\"suppressedMessages\":\"1259\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1260\",\"messages\":\"1261\",\"suppressedMessages\":\"1262\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1263\",\"messages\":\"1264\",\"suppressedMessages\":\"1265\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1266\",\"messages\":\"1267\",\"suppressedMessages\":\"1268\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1269\",\"messages\":\"1270\",\"suppressedMessages\":\"1271\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1272\",\"messages\":\"1273\",\"suppressedMessages\":\"1274\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1275\",\"messages\":\"1276\",\"suppressedMessages\":\"1277\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1278\",\"messages\":\"1279\",\"suppressedMessages\":\"1280\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1281\",\"messages\":\"1282\",\"suppressedMessages\":\"1283\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1284\",\"messages\":\"1285\",\"suppressedMessages\":\"1286\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1287\",\"messages\":\"1288\",\"suppressedMessages\":\"1289\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1290\",\"messages\":\"1291\",\"suppressedMessages\":\"1292\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1293\",\"messages\":\"1294\",\"suppressedMessages\":\"1295\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1296\",\"messages\":\"1297\",\"suppressedMessages\":\"1298\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1299\",\"messages\":\"1300\",\"suppressedMessages\":\"1301\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1302\",\"messages\":\"1303\",\"suppressedMessages\":\"1304\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1305\",\"messages\":\"1306\",\"suppressedMessages\":\"1307\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1308\",\"messages\":\"1309\",\"suppressedMessages\":\"1310\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1311\",\"messages\":\"1312\",\"suppressedMessages\":\"1313\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1314\",\"messages\":\"1315\",\"suppressedMessages\":\"1316\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1317\",\"messages\":\"1318\",\"suppressedMessages\":\"1319\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1320\",\"messages\":\"1321\",\"suppressedMessages\":\"1322\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1323\",\"messages\":\"1324\",\"suppressedMessages\":\"1325\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1326\",\"messages\":\"1327\",\"suppressedMessages\":\"1328\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1329\",\"messages\":\"1330\",\"suppressedMessages\":\"1331\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1332\",\"messages\":\"1333\",\"suppressedMessages\":\"1334\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1335\",\"messages\":\"1336\",\"suppressedMessages\":\"1337\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1338\",\"messages\":\"1339\",\"suppressedMessages\":\"1340\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1341\",\"messages\":\"1342\",\"suppressedMessages\":\"1343\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1344\",\"messages\":\"1345\",\"suppressedMessages\":\"1346\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1347\",\"messages\":\"1348\",\"suppressedMessages\":\"1349\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1350\",\"messages\":\"1351\",\"suppressedMessages\":\"1352\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1353\",\"messages\":\"1354\",\"suppressedMessages\":\"1355\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1356\",\"messages\":\"1357\",\"suppressedMessages\":\"1358\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1359\",\"messages\":\"1360\",\"suppressedMessages\":\"1361\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1362\",\"messages\":\"1363\",\"suppressedMessages\":\"1364\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1365\",\"messages\":\"1366\",\"suppressedMessages\":\"1367\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1368\",\"messages\":\"1369\",\"suppressedMessages\":\"1370\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1371\",\"messages\":\"1372\",\"suppressedMessages\":\"1373\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1374\",\"messages\":\"1375\",\"suppressedMessages\":\"1376\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1377\",\"messages\":\"1378\",\"suppressedMessages\":\"1379\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1380\",\"messages\":\"1381\",\"suppressedMessages\":\"1382\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1383\",\"messages\":\"1384\",\"suppressedMessages\":\"1385\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1386\",\"messages\":\"1387\",\"suppressedMessages\":\"1388\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1389\",\"messages\":\"1390\",\"suppressedMessages\":\"1391\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1392\",\"messages\":\"1393\",\"suppressedMessages\":\"1394\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1395\",\"messages\":\"1396\",\"suppressedMessages\":\"1397\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1398\",\"messages\":\"1399\",\"suppressedMessages\":\"1400\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1401\",\"messages\":\"1402\",\"suppressedMessages\":\"1403\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1404\",\"messages\":\"1405\",\"suppressedMessages\":\"1406\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1407\",\"messages\":\"1408\",\"suppressedMessages\":\"1409\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1410\",\"messages\":\"1411\",\"suppressedMessages\":\"1412\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1413\",\"messages\":\"1414\",\"suppressedMessages\":\"1415\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1416\",\"messages\":\"1417\",\"suppressedMessages\":\"1418\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1419\",\"messages\":\"1420\",\"suppressedMessages\":\"1421\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1422\",\"messages\":\"1423\",\"suppressedMessages\":\"1424\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1425\",\"messages\":\"1426\",\"suppressedMessages\":\"1427\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1428\",\"messages\":\"1429\",\"suppressedMessages\":\"1430\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1431\",\"messages\":\"1432\",\"suppressedMessages\":\"1433\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1434\",\"messages\":\"1435\",\"suppressedMessages\":\"1436\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1437\",\"messages\":\"1438\",\"suppressedMessages\":\"1439\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1440\",\"messages\":\"1441\",\"suppressedMessages\":\"1442\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1443\",\"messages\":\"1444\",\"suppressedMessages\":\"1445\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1446\",\"messages\":\"1447\",\"suppressedMessages\":\"1448\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1449\",\"messages\":\"1450\",\"suppressedMessages\":\"1451\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1452\",\"messages\":\"1453\",\"suppressedMessages\":\"1454\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1455\",\"messages\":\"1456\",\"suppressedMessages\":\"1457\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1458\",\"messages\":\"1459\",\"suppressedMessages\":\"1460\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1461\",\"messages\":\"1462\",\"suppressedMessages\":\"1463\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1464\",\"messages\":\"1465\",\"suppressedMessages\":\"1466\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1467\",\"messages\":\"1468\",\"suppressedMessages\":\"1469\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1470\",\"messages\":\"1471\",\"suppressedMessages\":\"1472\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1473\",\"messages\":\"1474\",\"suppressedMessages\":\"1475\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1476\",\"messages\":\"1477\",\"suppressedMessages\":\"1478\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1479\",\"messages\":\"1480\",\"suppressedMessages\":\"1481\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1482\",\"messages\":\"1483\",\"suppressedMessages\":\"1484\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1485\",\"messages\":\"1486\",\"suppressedMessages\":\"1487\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1488\",\"messages\":\"1489\",\"suppressedMessages\":\"1490\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1491\",\"messages\":\"1492\",\"suppressedMessages\":\"1493\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1494\",\"messages\":\"1495\",\"suppressedMessages\":\"1496\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1497\",\"messages\":\"1498\",\"suppressedMessages\":\"1499\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1500\",\"messages\":\"1501\",\"suppressedMessages\":\"1502\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1503\",\"messages\":\"1504\",\"suppressedMessages\":\"1505\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1506\",\"messages\":\"1507\",\"suppressedMessages\":\"1508\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1509\",\"messages\":\"1510\",\"suppressedMessages\":\"1511\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1512\",\"messages\":\"1513\",\"suppressedMessages\":\"1514\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1515\",\"messages\":\"1516\",\"suppressedMessages\":\"1517\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1518\",\"messages\":\"1519\",\"suppressedMessages\":\"1520\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1521\",\"messages\":\"1522\",\"suppressedMessages\":\"1523\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1524\",\"messages\":\"1525\",\"suppressedMessages\":\"1526\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1527\",\"messages\":\"1528\",\"suppressedMessages\":\"1529\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1530\",\"messages\":\"1531\",\"suppressedMessages\":\"1532\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1533\",\"messages\":\"1534\",\"suppressedMessages\":\"1535\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1536\",\"messages\":\"1537\",\"suppressedMessages\":\"1538\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1539\",\"messages\":\"1540\",\"suppressedMessages\":\"1541\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1542\",\"messages\":\"1543\",\"suppressedMessages\":\"1544\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1545\",\"messages\":\"1546\",\"suppressedMessages\":\"1547\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1548\",\"messages\":\"1549\",\"suppressedMessages\":\"1550\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1551\",\"messages\":\"1552\",\"suppressedMessages\":\"1553\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1554\",\"messages\":\"1555\",\"suppressedMessages\":\"1556\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1557\",\"messages\":\"1558\",\"suppressedMessages\":\"1559\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1560\",\"messages\":\"1561\",\"suppressedMessages\":\"1562\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1563\",\"messages\":\"1564\",\"suppressedMessages\":\"1565\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1566\",\"messages\":\"1567\",\"suppressedMessages\":\"1568\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1569\",\"messages\":\"1570\",\"suppressedMessages\":\"1571\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1572\",\"messages\":\"1573\",\"suppressedMessages\":\"1574\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1575\",\"messages\":\"1576\",\"suppressedMessages\":\"1577\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1578\",\"messages\":\"1579\",\"suppressedMessages\":\"1580\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1581\",\"messages\":\"1582\",\"suppressedMessages\":\"1583\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1584\",\"messages\":\"1585\",\"suppressedMessages\":\"1586\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1587\",\"messages\":\"1588\",\"suppressedMessages\":\"1589\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1590\",\"messages\":\"1591\",\"suppressedMessages\":\"1592\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1593\",\"messages\":\"1594\",\"suppressedMessages\":\"1595\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1596\",\"messages\":\"1597\",\"suppressedMessages\":\"1598\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1599\",\"messages\":\"1600\",\"suppressedMessages\":\"1601\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1602\",\"messages\":\"1603\",\"suppressedMessages\":\"1604\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1605\",\"messages\":\"1606\",\"suppressedMessages\":\"1607\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1608\",\"messages\":\"1609\",\"suppressedMessages\":\"1610\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1611\",\"messages\":\"1612\",\"suppressedMessages\":\"1613\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1614\",\"messages\":\"1615\",\"suppressedMessages\":\"1616\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1617\",\"messages\":\"1618\",\"suppressedMessages\":\"1619\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1620\",\"messages\":\"1621\",\"suppressedMessages\":\"1622\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1623\",\"messages\":\"1624\",\"suppressedMessages\":\"1625\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1626\",\"messages\":\"1627\",\"suppressedMessages\":\"1628\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1629\",\"messages\":\"1630\",\"suppressedMessages\":\"1631\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1632\",\"messages\":\"1633\",\"suppressedMessages\":\"1634\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1635\",\"messages\":\"1636\",\"suppressedMessages\":\"1637\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1638\",\"messages\":\"1639\",\"suppressedMessages\":\"1640\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1641\",\"messages\":\"1642\",\"suppressedMessages\":\"1643\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1644\",\"messages\":\"1645\",\"suppressedMessages\":\"1646\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1647\",\"messages\":\"1648\",\"suppressedMessages\":\"1649\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1650\",\"messages\":\"1651\",\"suppressedMessages\":\"1652\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1653\",\"messages\":\"1654\",\"suppressedMessages\":\"1655\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1656\",\"messages\":\"1657\",\"suppressedMessages\":\"1658\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1659\",\"messages\":\"1660\",\"suppressedMessages\":\"1661\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1662\",\"messages\":\"1663\",\"suppressedMessages\":\"1664\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1665\",\"messages\":\"1666\",\"suppressedMessages\":\"1667\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1668\",\"messages\":\"1669\",\"suppressedMessages\":\"1670\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1671\",\"messages\":\"1672\",\"suppressedMessages\":\"1673\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1674\",\"messages\":\"1675\",\"suppressedMessages\":\"1676\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1677\",\"messages\":\"1678\",\"suppressedMessages\":\"1679\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1680\",\"messages\":\"1681\",\"suppressedMessages\":\"1682\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1683\",\"messages\":\"1684\",\"suppressedMessages\":\"1685\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1686\",\"messages\":\"1687\",\"suppressedMessages\":\"1688\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1689\",\"messages\":\"1690\",\"suppressedMessages\":\"1691\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1692\",\"messages\":\"1693\",\"suppressedMessages\":\"1694\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1695\",\"messages\":\"1696\",\"suppressedMessages\":\"1697\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1698\",\"messages\":\"1699\",\"suppressedMessages\":\"1700\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1701\",\"messages\":\"1702\",\"suppressedMessages\":\"1703\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1704\",\"messages\":\"1705\",\"suppressedMessages\":\"1706\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1707\",\"messages\":\"1708\",\"suppressedMessages\":\"1709\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1710\",\"messages\":\"1711\",\"suppressedMessages\":\"1712\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1713\",\"messages\":\"1714\",\"suppressedMessages\":\"1715\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1716\",\"messages\":\"1717\",\"suppressedMessages\":\"1718\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1719\",\"messages\":\"1720\",\"suppressedMessages\":\"1721\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1722\",\"messages\":\"1723\",\"suppressedMessages\":\"1724\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1725\",\"messages\":\"1726\",\"suppressedMessages\":\"1727\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1728\",\"messages\":\"1729\",\"suppressedMessages\":\"1730\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1731\",\"messages\":\"1732\",\"suppressedMessages\":\"1733\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1734\",\"messages\":\"1735\",\"suppressedMessages\":\"1736\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1737\",\"messages\":\"1738\",\"suppressedMessages\":\"1739\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1740\",\"messages\":\"1741\",\"suppressedMessages\":\"1742\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1743\",\"messages\":\"1744\",\"suppressedMessages\":\"1745\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1746\",\"messages\":\"1747\",\"suppressedMessages\":\"1748\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1749\",\"messages\":\"1750\",\"suppressedMessages\":\"1751\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1752\",\"messages\":\"1753\",\"suppressedMessages\":\"1754\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1755\",\"messages\":\"1756\",\"suppressedMessages\":\"1757\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1758\",\"messages\":\"1759\",\"suppressedMessages\":\"1760\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1761\",\"messages\":\"1762\",\"suppressedMessages\":\"1763\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1764\",\"messages\":\"1765\",\"suppressedMessages\":\"1766\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1767\",\"messages\":\"1768\",\"suppressedMessages\":\"1769\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1770\",\"messages\":\"1771\",\"suppressedMessages\":\"1772\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1773\",\"messages\":\"1774\",\"suppressedMessages\":\"1775\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1776\",\"messages\":\"1777\",\"suppressedMessages\":\"1778\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1779\",\"messages\":\"1780\",\"suppressedMessages\":\"1781\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1782\",\"messages\":\"1783\",\"suppressedMessages\":\"1784\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1785\",\"messages\":\"1786\",\"suppressedMessages\":\"1787\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1788\",\"messages\":\"1789\",\"suppressedMessages\":\"1790\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1791\",\"messages\":\"1792\",\"suppressedMessages\":\"1793\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1794\",\"messages\":\"1795\",\"suppressedMessages\":\"1796\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1797\",\"messages\":\"1798\",\"suppressedMessages\":\"1799\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1800\",\"messages\":\"1801\",\"suppressedMessages\":\"1802\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1803\",\"messages\":\"1804\",\"suppressedMessages\":\"1805\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1806\",\"messages\":\"1807\",\"suppressedMessages\":\"1808\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1809\",\"messages\":\"1810\",\"suppressedMessages\":\"1811\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1812\",\"messages\":\"1813\",\"suppressedMessages\":\"1814\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1815\",\"messages\":\"1816\",\"suppressedMessages\":\"1817\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1818\",\"messages\":\"1819\",\"suppressedMessages\":\"1820\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1821\",\"messages\":\"1822\",\"suppressedMessages\":\"1823\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1824\",\"messages\":\"1825\",\"suppressedMessages\":\"1826\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1827\",\"messages\":\"1828\",\"suppressedMessages\":\"1829\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1830\",\"messages\":\"1831\",\"suppressedMessages\":\"1832\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1833\",\"messages\":\"1834\",\"suppressedMessages\":\"1835\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1836\",\"messages\":\"1837\",\"suppressedMessages\":\"1838\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1839\",\"messages\":\"1840\",\"suppressedMessages\":\"1841\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1842\",\"messages\":\"1843\",\"suppressedMessages\":\"1844\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1845\",\"messages\":\"1846\",\"suppressedMessages\":\"1847\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1848\",\"messages\":\"1849\",\"suppressedMessages\":\"1850\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1851\",\"messages\":\"1852\",\"suppressedMessages\":\"1853\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1854\",\"messages\":\"1855\",\"suppressedMessages\":\"1856\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1857\",\"messages\":\"1858\",\"suppressedMessages\":\"1859\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1860\",\"messages\":\"1861\",\"suppressedMessages\":\"1862\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1863\",\"messages\":\"1864\",\"suppressedMessages\":\"1865\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1866\",\"messages\":\"1867\",\"suppressedMessages\":\"1868\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1869\",\"messages\":\"1870\",\"suppressedMessages\":\"1871\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1872\",\"messages\":\"1873\",\"suppressedMessages\":\"1874\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1875\",\"messages\":\"1876\",\"suppressedMessages\":\"1877\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1878\",\"messages\":\"1879\",\"suppressedMessages\":\"1880\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1881\",\"messages\":\"1882\",\"suppressedMessages\":\"1883\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1884\",\"messages\":\"1885\",\"suppressedMessages\":\"1886\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1887\",\"messages\":\"1888\",\"suppressedMessages\":\"1889\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1890\",\"messages\":\"1891\",\"suppressedMessages\":\"1892\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1893\",\"messages\":\"1894\",\"suppressedMessages\":\"1895\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1896\",\"messages\":\"1897\",\"suppressedMessages\":\"1898\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1899\",\"messages\":\"1900\",\"suppressedMessages\":\"1901\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1902\",\"messages\":\"1903\",\"suppressedMessages\":\"1904\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1905\",\"messages\":\"1906\",\"suppressedMessages\":\"1907\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1908\",\"messages\":\"1909\",\"suppressedMessages\":\"1910\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1911\",\"messages\":\"1912\",\"suppressedMessages\":\"1913\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1914\",\"messages\":\"1915\",\"suppressedMessages\":\"1916\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1917\",\"messages\":\"1918\",\"suppressedMessages\":\"1919\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1920\",\"messages\":\"1921\",\"suppressedMessages\":\"1922\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1923\",\"messages\":\"1924\",\"suppressedMessages\":\"1925\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1926\",\"messages\":\"1927\",\"suppressedMessages\":\"1928\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1929\",\"messages\":\"1930\",\"suppressedMessages\":\"1931\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1932\",\"messages\":\"1933\",\"suppressedMessages\":\"1934\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1935\",\"messages\":\"1936\",\"suppressedMessages\":\"1937\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1938\",\"messages\":\"1939\",\"suppressedMessages\":\"1940\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1941\",\"messages\":\"1942\",\"suppressedMessages\":\"1943\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1944\",\"messages\":\"1945\",\"suppressedMessages\":\"1946\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1947\",\"messages\":\"1948\",\"suppressedMessages\":\"1949\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1950\",\"messages\":\"1951\",\"suppressedMessages\":\"1952\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1953\",\"messages\":\"1954\",\"suppressedMessages\":\"1955\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1956\",\"messages\":\"1957\",\"suppressedMessages\":\"1958\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1959\",\"messages\":\"1960\",\"suppressedMessages\":\"1961\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1962\",\"messages\":\"1963\",\"suppressedMessages\":\"1964\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1965\",\"messages\":\"1966\",\"suppressedMessages\":\"1967\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1968\",\"messages\":\"1969\",\"suppressedMessages\":\"1970\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1971\",\"messages\":\"1972\",\"suppressedMessages\":\"1973\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1974\",\"messages\":\"1975\",\"suppressedMessages\":\"1976\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1977\",\"messages\":\"1978\",\"suppressedMessages\":\"1979\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1980\",\"messages\":\"1981\",\"suppressedMessages\":\"1982\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1983\",\"messages\":\"1984\",\"suppressedMessages\":\"1985\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1986\",\"messages\":\"1987\",\"suppressedMessages\":\"1988\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1989\",\"messages\":\"1990\",\"suppressedMessages\":\"1991\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1992\",\"messages\":\"1993\",\"suppressedMessages\":\"1994\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1995\",\"messages\":\"1996\",\"suppressedMessages\":\"1997\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"1998\",\"messages\":\"1999\",\"suppressedMessages\":\"2000\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2001\",\"messages\":\"2002\",\"suppressedMessages\":\"2003\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2004\",\"messages\":\"2005\",\"suppressedMessages\":\"2006\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2007\",\"messages\":\"2008\",\"suppressedMessages\":\"2009\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2010\",\"messages\":\"2011\",\"suppressedMessages\":\"2012\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2013\",\"messages\":\"2014\",\"suppressedMessages\":\"2015\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2016\",\"messages\":\"2017\",\"suppressedMessages\":\"2018\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2019\",\"messages\":\"2020\",\"suppressedMessages\":\"2021\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2022\",\"messages\":\"2023\",\"suppressedMessages\":\"2024\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2025\",\"messages\":\"2026\",\"suppressedMessages\":\"2027\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2028\",\"messages\":\"2029\",\"suppressedMessages\":\"2030\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2031\",\"messages\":\"2032\",\"suppressedMessages\":\"2033\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2034\",\"messages\":\"2035\",\"suppressedMessages\":\"2036\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2037\",\"messages\":\"2038\",\"suppressedMessages\":\"2039\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2040\",\"messages\":\"2041\",\"suppressedMessages\":\"2042\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2043\",\"messages\":\"2044\",\"suppressedMessages\":\"2045\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2046\",\"messages\":\"2047\",\"suppressedMessages\":\"2048\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2049\",\"messages\":\"2050\",\"suppressedMessages\":\"2051\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2052\",\"messages\":\"2053\",\"suppressedMessages\":\"2054\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2055\",\"messages\":\"2056\",\"suppressedMessages\":\"2057\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2058\",\"messages\":\"2059\",\"suppressedMessages\":\"2060\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2061\",\"messages\":\"2062\",\"suppressedMessages\":\"2063\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2064\",\"messages\":\"2065\",\"suppressedMessages\":\"2066\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2067\",\"messages\":\"2068\",\"suppressedMessages\":\"2069\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2070\",\"messages\":\"2071\",\"suppressedMessages\":\"2072\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2073\",\"messages\":\"2074\",\"suppressedMessages\":\"2075\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2076\",\"messages\":\"2077\",\"suppressedMessages\":\"2078\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2079\",\"messages\":\"2080\",\"suppressedMessages\":\"2081\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2082\",\"messages\":\"2083\",\"suppressedMessages\":\"2084\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2085\",\"messages\":\"2086\",\"suppressedMessages\":\"2087\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2088\",\"messages\":\"2089\",\"suppressedMessages\":\"2090\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2091\",\"messages\":\"2092\",\"suppressedMessages\":\"2093\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2094\",\"messages\":\"2095\",\"suppressedMessages\":\"2096\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2097\",\"messages\":\"2098\",\"suppressedMessages\":\"2099\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2100\",\"messages\":\"2101\",\"suppressedMessages\":\"2102\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2103\",\"messages\":\"2104\",\"suppressedMessages\":\"2105\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2106\",\"messages\":\"2107\",\"suppressedMessages\":\"2108\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2109\",\"messages\":\"2110\",\"suppressedMessages\":\"2111\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2112\",\"messages\":\"2113\",\"suppressedMessages\":\"2114\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2115\",\"messages\":\"2116\",\"suppressedMessages\":\"2117\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2118\",\"messages\":\"2119\",\"suppressedMessages\":\"2120\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2121\",\"messages\":\"2122\",\"suppressedMessages\":\"2123\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2124\",\"messages\":\"2125\",\"suppressedMessages\":\"2126\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2127\",\"messages\":\"2128\",\"suppressedMessages\":\"2129\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2130\",\"messages\":\"2131\",\"suppressedMessages\":\"2132\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2133\",\"messages\":\"2134\",\"suppressedMessages\":\"2135\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2136\",\"messages\":\"2137\",\"suppressedMessages\":\"2138\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2139\",\"messages\":\"2140\",\"suppressedMessages\":\"2141\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2142\",\"messages\":\"2143\",\"suppressedMessages\":\"2144\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2145\",\"messages\":\"2146\",\"suppressedMessages\":\"2147\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2148\",\"messages\":\"2149\",\"suppressedMessages\":\"2150\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2151\",\"messages\":\"2152\",\"suppressedMessages\":\"2153\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2154\",\"messages\":\"2155\",\"suppressedMessages\":\"2156\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2157\",\"messages\":\"2158\",\"suppressedMessages\":\"2159\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2160\",\"messages\":\"2161\",\"suppressedMessages\":\"2162\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2163\",\"messages\":\"2164\",\"suppressedMessages\":\"2165\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2166\",\"messages\":\"2167\",\"suppressedMessages\":\"2168\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2169\",\"messages\":\"2170\",\"suppressedMessages\":\"2171\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2172\",\"messages\":\"2173\",\"suppressedMessages\":\"2174\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2175\",\"messages\":\"2176\",\"suppressedMessages\":\"2177\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2178\",\"messages\":\"2179\",\"suppressedMessages\":\"2180\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2181\",\"messages\":\"2182\",\"suppressedMessages\":\"2183\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2184\",\"messages\":\"2185\",\"suppressedMessages\":\"2186\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2187\",\"messages\":\"2188\",\"suppressedMessages\":\"2189\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2190\",\"messages\":\"2191\",\"suppressedMessages\":\"2192\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2193\",\"messages\":\"2194\",\"suppressedMessages\":\"2195\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2196\",\"messages\":\"2197\",\"suppressedMessages\":\"2198\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2199\",\"messages\":\"2200\",\"suppressedMessages\":\"2201\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2202\",\"messages\":\"2203\",\"suppressedMessages\":\"2204\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2205\",\"messages\":\"2206\",\"suppressedMessages\":\"2207\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2208\",\"messages\":\"2209\",\"suppressedMessages\":\"2210\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2211\",\"messages\":\"2212\",\"suppressedMessages\":\"2213\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2214\",\"messages\":\"2215\",\"suppressedMessages\":\"2216\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2217\",\"messages\":\"2218\",\"suppressedMessages\":\"2219\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2220\",\"messages\":\"2221\",\"suppressedMessages\":\"2222\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2223\",\"messages\":\"2224\",\"suppressedMessages\":\"2225\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2226\",\"messages\":\"2227\",\"suppressedMessages\":\"2228\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2229\",\"messages\":\"2230\",\"suppressedMessages\":\"2231\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2232\",\"messages\":\"2233\",\"suppressedMessages\":\"2234\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2235\",\"messages\":\"2236\",\"suppressedMessages\":\"2237\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2238\",\"messages\":\"2239\",\"suppressedMessages\":\"2240\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2241\",\"messages\":\"2242\",\"suppressedMessages\":\"2243\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2244\",\"messages\":\"2245\",\"suppressedMessages\":\"2246\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2247\",\"messages\":\"2248\",\"suppressedMessages\":\"2249\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2250\",\"messages\":\"2251\",\"suppressedMessages\":\"2252\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2253\",\"messages\":\"2254\",\"suppressedMessages\":\"2255\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2256\",\"messages\":\"2257\",\"suppressedMessages\":\"2258\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2259\",\"messages\":\"2260\",\"suppressedMessages\":\"2261\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2262\",\"messages\":\"2263\",\"suppressedMessages\":\"2264\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2265\",\"messages\":\"2266\",\"suppressedMessages\":\"2267\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2268\",\"messages\":\"2269\",\"suppressedMessages\":\"2270\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2271\",\"messages\":\"2272\",\"suppressedMessages\":\"2273\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2274\",\"messages\":\"2275\",\"suppressedMessages\":\"2276\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2277\",\"messages\":\"2278\",\"suppressedMessages\":\"2279\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2280\",\"messages\":\"2281\",\"suppressedMessages\":\"2282\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2283\",\"messages\":\"2284\",\"suppressedMessages\":\"2285\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2286\",\"messages\":\"2287\",\"suppressedMessages\":\"2288\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2289\",\"messages\":\"2290\",\"suppressedMessages\":\"2291\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2292\",\"messages\":\"2293\",\"suppressedMessages\":\"2294\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2295\",\"messages\":\"2296\",\"suppressedMessages\":\"2297\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2298\",\"messages\":\"2299\",\"suppressedMessages\":\"2300\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2301\",\"messages\":\"2302\",\"suppressedMessages\":\"2303\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2304\",\"messages\":\"2305\",\"suppressedMessages\":\"2306\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2307\",\"messages\":\"2308\",\"suppressedMessages\":\"2309\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2310\",\"messages\":\"2311\",\"suppressedMessages\":\"2312\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2313\",\"messages\":\"2314\",\"suppressedMessages\":\"2315\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2316\",\"messages\":\"2317\",\"suppressedMessages\":\"2318\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2319\",\"messages\":\"2320\",\"suppressedMessages\":\"2321\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2322\",\"messages\":\"2323\",\"suppressedMessages\":\"2324\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2325\",\"messages\":\"2326\",\"suppressedMessages\":\"2327\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2328\",\"messages\":\"2329\",\"suppressedMessages\":\"2330\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2331\",\"messages\":\"2332\",\"suppressedMessages\":\"2333\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2334\",\"messages\":\"2335\",\"suppressedMessages\":\"2336\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2337\",\"messages\":\"2338\",\"suppressedMessages\":\"2339\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2340\",\"messages\":\"2341\",\"suppressedMessages\":\"2342\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2343\",\"messages\":\"2344\",\"suppressedMessages\":\"2345\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2346\",\"messages\":\"2347\",\"suppressedMessages\":\"2348\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2349\",\"messages\":\"2350\",\"suppressedMessages\":\"2351\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2352\",\"messages\":\"2353\",\"suppressedMessages\":\"2354\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2355\",\"messages\":\"2356\",\"suppressedMessages\":\"2357\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2358\",\"messages\":\"2359\",\"suppressedMessages\":\"2360\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2361\",\"messages\":\"2362\",\"suppressedMessages\":\"2363\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2364\",\"messages\":\"2365\",\"suppressedMessages\":\"2366\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2367\",\"messages\":\"2368\",\"suppressedMessages\":\"2369\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2370\",\"messages\":\"2371\",\"suppressedMessages\":\"2372\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2373\",\"messages\":\"2374\",\"suppressedMessages\":\"2375\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2376\",\"messages\":\"2377\",\"suppressedMessages\":\"2378\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2379\",\"messages\":\"2380\",\"suppressedMessages\":\"2381\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2382\",\"messages\":\"2383\",\"suppressedMessages\":\"2384\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2385\",\"messages\":\"2386\",\"suppressedMessages\":\"2387\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2388\",\"messages\":\"2389\",\"suppressedMessages\":\"2390\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2391\",\"messages\":\"2392\",\"suppressedMessages\":\"2393\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2394\",\"messages\":\"2395\",\"suppressedMessages\":\"2396\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2397\",\"messages\":\"2398\",\"suppressedMessages\":\"2399\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2400\",\"messages\":\"2401\",\"suppressedMessages\":\"2402\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2403\",\"messages\":\"2404\",\"suppressedMessages\":\"2405\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},{\"filePath\":\"2406\",\"messages\":\"2407\",\"suppressedMessages\":\"2408\",\"errorCount\":0,\"fatalErrorCount\":0,\"warningCount\":0,\"fixableErrorCount\":0,\"fixableWarningCount\":0},\"/home/pooya/Code/nitro/AGENTS.md\",[],[],\"/home/pooya/Code/nitro/CHANGELOG.md\",[],[],\"/home/pooya/Code/nitro/CLAUDE.md\",[],[],\"/home/pooya/Code/nitro/CODE_OF_CONDUCT.md\",[],[],\"/home/pooya/Code/nitro/CONTRIBUTING.md\",[],[],\"/home/pooya/Code/nitro/README.md\",[],[],\"/home/pooya/Code/nitro/SECURITY.md\",[],[],\"/home/pooya/Code/nitro/automd.config.ts\",[],[],\"/home/pooya/Code/nitro/build.config.ts\",[],[],\"/home/pooya/Code/nitro/changelog.config.ts\",[],[],\"/home/pooya/Code/nitro/docs/.config/automd.config.ts\",[],[],\"/home/pooya/Code/nitro/eslint.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/api-routes/api/hello/[name].ts\",[],[],\"/home/pooya/Code/nitro/examples/api-routes/api/hello.ts\",[],[],\"/home/pooya/Code/nitro/examples/api-routes/api/test.get.ts\",[],[],\"/home/pooya/Code/nitro/examples/api-routes/api/test.post.ts\",[],[],\"/home/pooya/Code/nitro/examples/api-routes/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/api-routes/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/auto-imports/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/auto-imports/server/utils/hello.ts\",[],[],\"/home/pooya/Code/nitro/examples/auto-imports/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/auto-imports/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/cached-handler/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/cached-handler/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/cached-handler/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/custom-error-handler/error.ts\",[],[],\"/home/pooya/Code/nitro/examples/custom-error-handler/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/custom-error-handler/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/custom-error-handler/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/database/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/database/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/database/tasks/db/migrate.ts\",[],[],\"/home/pooya/Code/nitro/examples/database/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/elysia/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/elysia/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/elysia/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/express/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/express/server.node.ts\",[],[],\"/home/pooya/Code/nitro/examples/express/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/fastify/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/fastify/server.node.ts\",[],[],\"/home/pooya/Code/nitro/examples/fastify/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/hello-world/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/hello-world/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/hello-world/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/hono/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/hono/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/hono/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/import-alias/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/import-alias/server/routes/index.ts\",[],[],\"/home/pooya/Code/nitro/examples/import-alias/server/utils/math.ts\",[],[],\"/home/pooya/Code/nitro/examples/import-alias/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/middleware/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/middleware/server/middleware/auth.ts\",[],[],\"/home/pooya/Code/nitro/examples/middleware/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/middleware/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/mono-jsx/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/mono-jsx/server.tsx\",[],[],\"/home/pooya/Code/nitro/examples/mono-jsx/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/nano-jsx/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/nano-jsx/server.tsx\",[],[],\"/home/pooya/Code/nitro/examples/nano-jsx/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/plugins/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/plugins/server/plugins/test.ts\",[],[],\"/home/pooya/Code/nitro/examples/plugins/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/plugins/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/renderer/api/hello.ts\",[],[],\"/home/pooya/Code/nitro/examples/renderer/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/renderer/renderer.ts\",[],[],\"/home/pooya/Code/nitro/examples/renderer/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/runtime-config/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/runtime-config/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/runtime-config/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/server-fetch/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/server-fetch/routes/hello.ts\",[],[],\"/home/pooya/Code/nitro/examples/server-fetch/routes/index.ts\",[],[],\"/home/pooya/Code/nitro/examples/server-fetch/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/shiki/api/highlight.ts\",[],[],\"/home/pooya/Code/nitro/examples/shiki/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/shiki/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/virtual-routes/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/virtual-routes/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-nitro-plugin/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-rsc/app/action.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-rsc/app/client.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/entry.browser.tsx\",[],[\"2409\"],\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/entry.rsc.tsx\",[],[\"2410\"],\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/entry.ssr.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/error-boundary.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-rsc/app/framework/request.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-rsc/app/root.tsx\",[],[\"2411\"],\"/home/pooya/Code/nitro/examples/vite-rsc/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-html/app/entry-server.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-html/routes/quote.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-html/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-preact/src/app.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-preact/src/entry-client.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-preact/src/entry-server.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-preact/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-react/src/app.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-react/src/entry-client.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-react/src/entry-server.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-react/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-solid/src/app.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-solid/src/entry-client.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-solid/src/entry-server.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-solid/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/src/main.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/src/routes/__root.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/src/routes/index.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tsr-react/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/server.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/router.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/routes/__root.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/routes/api/test.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/src/routes/index.tsx\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-tss-react/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/entry-client.ts\",[],[\"2412\"],\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/entry-server.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/routes.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/app/shims.d.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-ssr-vue-router/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/examples/vite-trpc/server/trpc.ts\",[],[],\"/home/pooya/Code/nitro/examples/vite-trpc/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/websocket/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/examples/websocket/routes/_ws.ts\",[],[],\"/home/pooya/Code/nitro/examples/websocket/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/lib/h3.d.mts\",[],[],\"/home/pooya/Code/nitro/lib/h3.mjs\",[],[],\"/home/pooya/Code/nitro/lib/vite.types.d.mts\",[],[],\"/home/pooya/Code/nitro/lib/vite.types.mjs\",[],[\"2413\"],\"/home/pooya/Code/nitro/playground/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/playground/server.ts\",[],[],\"/home/pooya/Code/nitro/playground/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/scripts/bump-nightly.ts\",[],[\"2414\",\"2415\"],\"/home/pooya/Code/nitro/scripts/gen-node-compat.ts\",[],[],\"/home/pooya/Code/nitro/scripts/gen-presets.ts\",[],[],\"/home/pooya/Code/nitro/src/build/assets.ts\",[],[],\"/home/pooya/Code/nitro/src/build/build.ts\",[],[],\"/home/pooya/Code/nitro/src/build/chunks.ts\",[],[],\"/home/pooya/Code/nitro/src/build/config.ts\",[],[],\"/home/pooya/Code/nitro/src/build/info.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins/externals.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins/oxc.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins/raw.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins/route-meta.ts\",[],[\"2416\"],\"/home/pooya/Code/nitro/src/build/plugins/server-main.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins/sourcemap-min.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins/virtual.ts\",[],[],\"/home/pooya/Code/nitro/src/build/plugins.ts\",[],[],\"/home/pooya/Code/nitro/src/build/prepare.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rolldown/build.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rolldown/config.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rolldown/dev.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rolldown/prod.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rollup/build.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rollup/config.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rollup/dev.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rollup/error.ts\",[],[],\"/home/pooya/Code/nitro/src/build/rollup/prod.ts\",[],[],\"/home/pooya/Code/nitro/src/build/types.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/_all.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/database.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/error-handler.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/feature-flags.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/plugins.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/polyfills.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/public-assets.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/renderer-template.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/routing-meta.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/routing.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/runtime-config.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/server-assets.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/storage.ts\",[],[],\"/home/pooya/Code/nitro/src/build/virtual/tasks.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/build.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/bundler.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/dev.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/env.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/plugin.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/preview.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/prod.ts\",[],[],\"/home/pooya/Code/nitro/src/build/vite/types.ts\",[],[],\"/home/pooya/Code/nitro/src/builder.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/commands/build.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/commands/dev.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/commands/prepare.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/commands/task/index.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/commands/task/list.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/commands/task/run.ts\",[],[\"2417\"],\"/home/pooya/Code/nitro/src/cli/common.ts\",[],[],\"/home/pooya/Code/nitro/src/cli/index.ts\",[],[],\"/home/pooya/Code/nitro/src/config/defaults.ts\",[],[],\"/home/pooya/Code/nitro/src/config/loader.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/assets.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/builder.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/compatibility.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/database.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/error.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/export-conditions.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/imports.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/open-api.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/paths.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/route-rules.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/runtime-config.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/storage.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/tsconfig.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/unenv.ts\",[],[],\"/home/pooya/Code/nitro/src/config/resolvers/url.ts\",[],[],\"/home/pooya/Code/nitro/src/config/update.ts\",[],[],\"/home/pooya/Code/nitro/src/dev/app.ts\",[],[],\"/home/pooya/Code/nitro/src/dev/server.ts\",[],[],\"/home/pooya/Code/nitro/src/dev/vfs.ts\",[],[],\"/home/pooya/Code/nitro/src/global.ts\",[],[],\"/home/pooya/Code/nitro/src/module.ts\",[],[],\"/home/pooya/Code/nitro/src/nitro.ts\",[],[],\"/home/pooya/Code/nitro/src/prerender/prerender.ts\",[],[],\"/home/pooya/Code/nitro/src/prerender/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_nitro/base-worker.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_nitro/nitro-dev.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_nitro/nitro-prerender.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_nitro/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_nitro/runtime/nitro-dev.ts\",[],[\"2418\"],\"/home/pooya/Code/nitro/src/presets/_nitro/runtime/nitro-prerenderer.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_nitro/runtime/service-worker.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_resolve.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_static/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_utils/fs.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/_utils/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/alwaysdata/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-amplify/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-amplify/runtime/aws-amplify.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-amplify/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-amplify/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-lambda/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-lambda/runtime/_utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-lambda/runtime/aws-lambda-streaming.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-lambda/runtime/aws-lambda.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/aws-lambda/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/azure/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/azure/runtime/_utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/azure/runtime/azure-swa.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/azure/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/azure/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/bun/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/bun/runtime/bun.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cleavr/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/dev.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/entry-exports.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/_module-handler.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/cloudflare-durable.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/cloudflare-module.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/cloudflare-pages.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/plugin.dev.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/runtime/shims/workers.dev.mjs\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/unenv/node-compat.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/unenv/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/wrangler/_utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/wrangler/config.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/cloudflare/wrangler/environment.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/deno/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/deno/runtime/deno-deploy.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/deno/runtime/deno-server.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/deno/unenv/node-compat.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/deno/unenv/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/digitalocean/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/firebase/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/firebase/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/flightcontrol/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/genezio/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/heroku/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/iis/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/iis/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/index.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/koyeb/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/netlify/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/netlify/runtime/netlify-edge.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/netlify/runtime/netlify.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/netlify/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/netlify/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/node/cluster.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/node/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/node/runtime/node-cluster.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/node/runtime/node-middleware.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/node/runtime/node-server.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/platform.sh/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/render.com/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/standard/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/standard/runtime/server.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/stormkit/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/stormkit/runtime/stormkit.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/vercel/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/vercel/runtime/isr.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/vercel/runtime/vercel.node.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/vercel/runtime/vercel.web.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/vercel/types.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/vercel/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/winterjs/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/winterjs/runtime/winterjs.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/zeabur/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/zeabur/runtime/zeabur.ts\",[],[],\"/home/pooya/Code/nitro/src/presets/zerops/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/routing.ts\",[],[],\"/home/pooya/Code/nitro/src/runner/node.ts\",[],[\"2419\"],\"/home/pooya/Code/nitro/src/runner/proxy.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/app.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/cache.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/config.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/context.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/database.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/app.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/cache.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/context.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/database.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/empty.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/error/dev.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/error/hooks.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/error/prod.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/error/utils.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/meta.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/plugin.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/route-rules.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/routes/dev-tasks.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/routes/openapi.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/routes/renderer-template.dev.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/routes/renderer-template.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/routes/scalar.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/routes/swagger.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/runtime-config.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/static.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/storage.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/task.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/vite/dev-entry.mjs\",[],[],\"/home/pooya/Code/nitro/src/runtime/internal/vite/node-runner.mjs\",[],[\"2420\"],\"/home/pooya/Code/nitro/src/runtime/internal/vite/ssr-renderer.mjs\",[],[],\"/home/pooya/Code/nitro/src/runtime/meta.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/nitro.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/runtime-config.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/storage.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/task.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/_runtime_warn.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/database.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/error-handler.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/feature-flags.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/plugins.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/polyfills.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/public-assets.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/renderer-template.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/routing-meta.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/routing.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/runtime-config.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/server-assets.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/storage.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/virtual/tasks.ts\",[],[],\"/home/pooya/Code/nitro/src/runtime/vite.ts\",[],[],\"/home/pooya/Code/nitro/src/scan.ts\",[],[],\"/home/pooya/Code/nitro/src/task.ts\",[],[],\"/home/pooya/Code/nitro/src/types/_utils.ts\",[],[\"2421\"],\"/home/pooya/Code/nitro/src/types/build.ts\",[],[],\"/home/pooya/Code/nitro/src/types/config.ts\",[],[],\"/home/pooya/Code/nitro/src/types/fetch/_match.ts\",[],[],\"/home/pooya/Code/nitro/src/types/fetch/_serialize.ts\",[],[\"2422\"],\"/home/pooya/Code/nitro/src/types/fetch/fetch.ts\",[],[\"2423\"],\"/home/pooya/Code/nitro/src/types/fetch/index.ts\",[],[],\"/home/pooya/Code/nitro/src/types/global.ts\",[],[\"2424\"],\"/home/pooya/Code/nitro/src/types/h3.ts\",[],[\"2425\"],\"/home/pooya/Code/nitro/src/types/handler.ts\",[],[],\"/home/pooya/Code/nitro/src/types/hooks.ts\",[],[],\"/home/pooya/Code/nitro/src/types/index.ts\",[],[],\"/home/pooya/Code/nitro/src/types/module.ts\",[],[],\"/home/pooya/Code/nitro/src/types/nitro.ts\",[],[],\"/home/pooya/Code/nitro/src/types/openapi-ts.ts\",[],[],\"/home/pooya/Code/nitro/src/types/openapi.ts\",[],[],\"/home/pooya/Code/nitro/src/types/prerender.ts\",[],[],\"/home/pooya/Code/nitro/src/types/preset.ts\",[],[],\"/home/pooya/Code/nitro/src/types/route-rules.ts\",[],[],\"/home/pooya/Code/nitro/src/types/runner.ts\",[],[],\"/home/pooya/Code/nitro/src/types/runtime/asset.ts\",[],[],\"/home/pooya/Code/nitro/src/types/runtime/cache.ts\",[],[],\"/home/pooya/Code/nitro/src/types/runtime/index.ts\",[],[],\"/home/pooya/Code/nitro/src/types/runtime/nitro.ts\",[],[],\"/home/pooya/Code/nitro/src/types/runtime/task.ts\",[],[],\"/home/pooya/Code/nitro/src/types/srvx.ts\",[],[],\"/home/pooya/Code/nitro/src/utils/compress.ts\",[],[],\"/home/pooya/Code/nitro/src/utils/dep.ts\",[],[],\"/home/pooya/Code/nitro/src/utils/fs-tree.ts\",[],[],\"/home/pooya/Code/nitro/src/utils/fs.ts\",[],[\"2426\"],\"/home/pooya/Code/nitro/src/utils/parallel.ts\",[],[],\"/home/pooya/Code/nitro/src/utils/regex.ts\",[],[],\"/home/pooya/Code/nitro/src/vite.ts\",[],[],\"/home/pooya/Code/nitro/test/examples.test.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/error.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/exports.cloudflare.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/public/foo.js\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/files/sqlts.sql.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/middleware/_ignored.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/plugins/errors.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/plugins/vary.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/(route-group)/route-group.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/500.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/_ignored.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/cached.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/db.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/echo.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/error.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/errors.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/headers.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/hello.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/hey/index.get.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/kebab.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/meta/test.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/methods/foo.get.get.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/methods/get.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/param/[test-id].ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/storage/item.get.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/storage/item.put.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/upload.post.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/api/wildcard/[...param].ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/assets/[id].ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/assets/all.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/assets/md.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/config.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/context.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/env/index.dev.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/env/index.get.prod.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/error-stack.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/fetch.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/file.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/icon.png.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/imports.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/json-string.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/jsx.tsx\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/modules.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/node-compat.ts\",[],[\"2427\",\"2428\",\"2429\"],\"/home/pooya/Code/nitro/test/fixture/server/routes/prerender-custom.html.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/prerender.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/raw.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/replace.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/rules/[...slug].ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/static-flags.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/stream.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/tasks/[...name].ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/wait-until.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/wasm/dynamic-import.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/routes/wasm/static-import.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/tasks/db/migrate.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/tasks/test.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/utils/foo/bar/test.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/utils/foo/test.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server/utils/test.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server.config.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/server.ts\",[],[],\"/home/pooya/Code/nitro/test/fixture/vite.config.ts\",[],[],\"/home/pooya/Code/nitro/test/minimal/minimal.test.ts\",[],[],\"/home/pooya/Code/nitro/test/minimal/nitro.config.ts\",[],[],\"/home/pooya/Code/nitro/test/minimal/server.ts\",[],[],\"/home/pooya/Code/nitro/test/minimal/vite.config.mjs\",[],[],\"/home/pooya/Code/nitro/test/presets/aws-lambda.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/azure-swa.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/bun.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/cloudflare-module.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/cloudflare-pages.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/deno-server.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/netlify.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/nitro-dev.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/node.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/standard.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/static.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/vercel.test.ts\",[],[],\"/home/pooya/Code/nitro/test/presets/winterjs.test.ts\",[],[],\"/home/pooya/Code/nitro/test/scripts/gen-fixture-types.ts\",[],[],\"/home/pooya/Code/nitro/test/tests.ts\",[],[],\"/home/pooya/Code/nitro/test/unit/azure.utils.test.ts\",[],[],\"/home/pooya/Code/nitro/test/unit/runtime-config.env.test.ts\",[],[],\"/home/pooya/Code/nitro/test/unit/runtime-config.test.ts\",[],[],\"/home/pooya/Code/nitro/test/unit/virtual.test.ts\",[],[],\"/home/pooya/Code/nitro/vitest.config.ts\",[],[],{\"ruleId\":\"2430\",\"severity\":2,\"message\":\"2431\",\"line\":139,\"column\":1,\"nodeType\":\"2432\",\"messageId\":\"2433\",\"endLine\":139,\"endColumn\":7,\"suggestions\":\"2434\",\"suppressions\":\"2435\"},{\"ruleId\":\"2436\",\"severity\":2,\"message\":\"2437\",\"line\":53,\"column\":28,\"nodeType\":\"2432\",\"messageId\":\"2438\",\"endLine\":53,\"endColumn\":52,\"suppressions\":\"2439\"},{\"ruleId\":\"2440\",\"severity\":2,\"message\":\"2441\",\"line\":13,\"column\":23,\"nodeType\":\"2442\",\"messageId\":\"2443\",\"endLine\":13,\"endColumn\":30,\"suggestions\":\"2444\",\"suppressions\":\"2445\"},{\"ruleId\":\"2430\",\"severity\":2,\"message\":\"2431\",\"line\":15,\"column\":1,\"nodeType\":\"2432\",\"messageId\":\"2433\",\"endLine\":15,\"endColumn\":7,\"suggestions\":\"2446\",\"suppressions\":\"2447\"},{\"ruleId\":\"2448\",\"severity\":2,\"message\":\"2449\",\"line\":2,\"column\":8,\"nodeType\":\"2450\",\"messageId\":\"2451\",\"endLine\":2,\"endColumn\":10,\"fix\":\"2452\",\"suppressions\":\"2453\"},{\"ruleId\":\"2430\",\"severity\":2,\"message\":\"2454\",\"line\":143,\"column\":8,\"nodeType\":\"2455\",\"messageId\":\"2456\",\"endLine\":143,\"endColumn\":13,\"suppressions\":\"2457\"},{\"ruleId\":\"2458\",\"severity\":2,\"message\":\"2459\",\"line\":146,\"column\":3,\"nodeType\":\"2432\",\"messageId\":\"2460\",\"endLine\":146,\"endColumn\":18,\"suppressions\":\"2461\"},{\"ruleId\":\"2462\",\"severity\":2,\"message\":\"2463\",\"line\":16,\"column\":21,\"nodeType\":\"2442\",\"messageId\":\"2464\",\"endLine\":16,\"endColumn\":45,\"suppressions\":\"2465\"},{\"ruleId\":\"2458\",\"severity\":2,\"message\":\"2459\",\"line\":55,\"column\":7,\"nodeType\":\"2432\",\"messageId\":\"2460\",\"endLine\":55,\"endColumn\":22,\"suppressions\":\"2466\"},{\"ruleId\":\"2430\",\"severity\":2,\"message\":\"2454\",\"line\":32,\"column\":4,\"nodeType\":\"2455\",\"messageId\":\"2456\",\"endLine\":32,\"endColumn\":9,\"suppressions\":\"2467\"},{\"ruleId\":\"2468\",\"severity\":2,\"message\":\"2469\",\"line\":124,\"column\":45,\"nodeType\":\"2470\",\"messageId\":\"2471\",\"endLine\":124,\"endColumn\":77,\"fix\":\"2472\",\"suppressions\":\"2473\"},{\"ruleId\":\"2430\",\"severity\":2,\"message\":\"2474\",\"line\":185,\"column\":1,\"nodeType\":\"2432\",\"messageId\":\"2433\",\"endLine\":185,\"endColumn\":9,\"suggestions\":\"2475\",\"suppressions\":\"2476\"},{\"ruleId\":\"2477\",\"severity\":2,\"message\":\"2478\",\"line\":16,\"column\":47,\"nodeType\":\"2455\",\"messageId\":\"2479\",\"endLine\":16,\"endColumn\":55,\"suppressions\":\"2480\"},{\"ruleId\":\"2477\",\"severity\":2,\"message\":\"2478\",\"line\":13,\"column\":37,\"nodeType\":\"2455\",\"messageId\":\"2479\",\"endLine\":13,\"endColumn\":45,\"suppressions\":\"2481\"},{\"ruleId\":\"2448\",\"severity\":2,\"message\":\"2449\",\"line\":116,\"column\":13,\"nodeType\":\"2450\",\"messageId\":\"2451\",\"endLine\":116,\"endColumn\":15,\"fix\":\"2482\",\"suppressions\":\"2483\"},{\"ruleId\":\"2448\",\"severity\":2,\"message\":\"2449\",\"line\":22,\"column\":13,\"nodeType\":\"2450\",\"messageId\":\"2451\",\"endLine\":22,\"endColumn\":15,\"fix\":\"2484\",\"suppressions\":\"2485\"},{\"ruleId\":\"2448\",\"severity\":2,\"message\":\"2449\",\"line\":28,\"column\":13,\"nodeType\":\"2450\",\"messageId\":\"2451\",\"endLine\":28,\"endColumn\":15,\"fix\":\"2486\",\"suppressions\":\"2487\"},{\"ruleId\":\"2462\",\"severity\":2,\"message\":\"2463\",\"line\":32,\"column\":7,\"nodeType\":\"2442\",\"messageId\":\"2464\",\"endLine\":32,\"endColumn\":19,\"suppressions\":\"2488\"},{\"ruleId\":\"2489\",\"severity\":2,\"message\":\"2490\",\"line\":8,\"column\":41,\"nodeType\":\"2455\",\"messageId\":\"2491\",\"endLine\":8,\"endColumn\":47,\"fix\":\"2492\",\"suppressions\":\"2493\"},{\"ruleId\":\"2489\",\"severity\":2,\"message\":\"2490\",\"line\":10,\"column\":50,\"nodeType\":\"2455\",\"messageId\":\"2491\",\"endLine\":10,\"endColumn\":56,\"fix\":\"2494\",\"suppressions\":\"2495\"},{\"ruleId\":\"2489\",\"severity\":2,\"message\":\"2490\",\"line\":12,\"column\":53,\"nodeType\":\"2455\",\"messageId\":\"2491\",\"endLine\":12,\"endColumn\":59,\"fix\":\"2496\",\"suppressions\":\"2497\"},\"unicorn/prefer-top-level-await\",\"Prefer top-level await over an async function `main` call.\",\"CallExpression\",\"identifier\",[\"2498\"],[\"2499\"],\"prefer-spread\",\"Use the spread operator instead of '.apply()'.\",\"preferSpread\",[\"2500\"],\"unicorn/text-encoding-identifier-case\",\"Prefer `utf-8` over `UTF-8`.\",\"Literal\",\"text-encoding-identifier/error\",[\"2501\"],[\"2502\"],[\"2503\"],[\"2504\"],\"unicorn/require-module-specifiers\",\"export statement without specifiers is not allowed.\",\"ExportNamedDeclaration\",\"error\",{\"range\":\"2505\",\"text\":\"2506\"},[\"2507\"],\"Prefer top-level await over using a promise chain.\",\"Identifier\",\"promise\",[\"2508\"],\"unicorn/no-process-exit\",\"Only use `process.exit()` in CLI apps. Throw an error instead.\",\"no-process-exit\",[\"2509\"],\"no-control-regex\",\"Unexpected control character(s) in regular expression: \\\\x00.\",\"unexpected\",[\"2510\"],[\"2511\"],[\"2512\"],\"unicorn/no-nested-ternary\",\"Nested ternary expression should be parenthesized.\",\"ConditionalExpression\",\"should-parenthesized\",{\"range\":\"2513\",\"text\":\"2514\"},[\"2515\"],\"Prefer top-level await over an async function `reload` call.\",[\"2516\"],[\"2517\"],\"@typescript-eslint/no-unsafe-function-type\",\"The `Function` type accepts any function-like value.\\nPrefer explicitly defining any function parameters and return type.\",\"bannedFunctionType\",[\"2518\"],[\"2519\"],{\"range\":\"2520\",\"text\":\"2506\"},[\"2521\"],{\"range\":\"2522\",\"text\":\"2506\"},[\"2523\"],{\"range\":\"2524\",\"text\":\"2506\"},[\"2525\"],[\"2526\"],\"unicorn/prefer-global-this\",\"Prefer `globalThis` over `global`.\",\"prefer-global-this/error\",{\"range\":\"2527\",\"text\":\"2528\"},[\"2529\"],{\"range\":\"2530\",\"text\":\"2528\"},[\"2531\"],{\"range\":\"2532\",\"text\":\"2528\"},[\"2533\"],{\"messageId\":\"2534\",\"fix\":\"2535\",\"data\":\"2536\",\"desc\":\"2537\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"messageId\":\"2539\",\"fix\":\"2540\",\"data\":\"2541\",\"desc\":\"2542\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"messageId\":\"2534\",\"fix\":\"2543\",\"data\":\"2544\",\"desc\":\"2537\"},{\"kind\":\"2538\",\"justification\":\"2506\"},[62,72],\"\",{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},[3173,3205],\"(this.ready ? \\\"ready\\\" : \\\"pending\\\")\",{\"kind\":\"2538\",\"justification\":\"2506\"},{\"messageId\":\"2534\",\"fix\":\"2545\",\"data\":\"2546\",\"desc\":\"2537\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},[3539,3554],{\"kind\":\"2538\",\"justification\":\"2506\"},[484,499],{\"kind\":\"2538\",\"justification\":\"2506\"},[830,845],{\"kind\":\"2538\",\"justification\":\"2506\"},{\"kind\":\"2538\",\"justification\":\"2506\"},[256,262],\"globalThis\",{\"kind\":\"2538\",\"justification\":\"2506\"},[372,378],{\"kind\":\"2538\",\"justification\":\"2506\"},[498,504],{\"kind\":\"2538\",\"justification\":\"2506\"},\"add-await\",{\"range\":\"2547\",\"text\":\"2548\"},{\"name\":\"2549\"},\"Insert `await`.\",\"directive\",\"text-encoding-identifier/suggestion\",{\"range\":\"2550\",\"text\":\"2551\"},{\"value\":\"2552\",\"replacement\":\"2551\"},\"Replace `UTF-8` with `utf-8`.\",{\"range\":\"2553\",\"text\":\"2548\"},{\"name\":\"2549\"},{\"range\":\"2554\",\"text\":\"2548\"},{\"name\":\"2555\"},[4351,4351],\"await \",\"main\",[530,535],\"utf-8\",\"UTF-8\",[414,414],[4829,4829],\"reload\"]"
  },
  {
    "path": ".gitattributes",
    "content": "*.txt\ttext eol=lf\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "* @pi0"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "content": "name: \"\\U0001F41E Bug report\"\ndescription: Report an issue or bug\nlabels: [\"pending triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        If bug-report is related to Nuxt framework, please open an issue directly there:\n        https://github.com/nuxt/nuxt/issues/new/choose\n\n        Please use one of the templates below to create a minimal reproduction :\n\n        👉 https://stackblitz.com/github/nitrojs/nitro/tree/starter\n        👉 https://codesandbox.io/p/github/nitrojs/nitro/starter\n  - type: textarea\n    id: bug-env\n    attributes:\n      label: Environment\n      description: Nitro and Node.js version possibly nitro config can be helpful to investigate issues\n      placeholder: Environment\n    validations:\n      required: true\n  - type: textarea\n    id: reproduction\n    attributes:\n      label: Reproduction\n      description: Please provide a link to a repo that can reproduce the problem you ran into. A **minimal reproduction** is required unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a \"need reproduction\" label. If no reproduction is provided we might close it.\n      placeholder: Reproduction\n    validations:\n      required: true\n  - type: textarea\n    id: bug-description\n    attributes:\n      label: Describe the bug\n      description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!\n      placeholder: Bug description\n    validations:\n      required: true\n  - type: textarea\n    id: additional\n    attributes:\n      label: Additional context\n      description: If applicable, add any other context about the problem here\n  - type: textarea\n    id: logs\n    attributes:\n      label: Logs\n      description: |\n        Optional if provided reproduction. Please try not to insert an image but copy paste the log text.\n      render: sh\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: 📚 Nitro Documentation\n    url: https://nitro.build/\n    about: Check the documentation for usage of Nuxt 3\n  - name: 💬 Discussions\n    url: https://github.com/nitrojs/nitro/discussions\n    about: Use discussions if you have an idea for improvement and asking questions\n  - name: 🔗 Nuxt related Issues\n    url: https://github.com/nuxt/nuxt/issues/new/choose\n    about: Please open an issue in nuxt/nuxt to discuss\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "content": "name: \"🚀 Feature request\"\ndescription: Suggest a feature or improvement\nlabels: [\"pending triage\"]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thank you for taking the time to fill out this feature request!\n  - type: textarea\n    id: feature-description\n    attributes:\n      label: Describe the feature\n      description: A clear and concise description of what you think would be a helpful addition, including the possible use cases and alternatives you have considered. If you have a working prototype or module that implements it, please include a link.\n      placeholder: Feature description\n    validations:\n      required: true\n  - type: checkboxes\n    id: additional-info\n    attributes:\n      label: Additional information\n      description: Additional information that helps us decide how to proceed.\n      options:\n        - label: Would you be willing to help implement this feature?\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!---\n\n*** IMPORTANT: PLEASE READ BEFORE CONTINUING TO MAKE A PULL REQUEST ***\n\n- The title should follow conventional commits (https://conventionalcommits.org).\n\n- If it is a bug fix, please ensure there is a linked issue with minimal (nitro) reproduction and/or enough context to explain exactly what it is fixing and why this fix is the best option in Nitro.\n\n- If it is a security fix, please always report it first as per https://github.com/nitrojs/nitro/blob/main/SECURITY.md\n\n- If it is a new feature, please ensure it has already been discussed. Keep the scope of changes minimal to what is essential, and try to break down your changes into smaller PRs when possible.\n\n- If you are submitting a new preset, please, in addition to the docs, ALWAYS add a new preset in src/presets.\n\n- After submitting, please remain patient until your PR is reviewed.\n\nThanks for your contribution ❤️\n-->\n\n### 🔗 Linked issue\n\n<!-- Please ensure there is an open issue and mention its number as #123 -->\n\n### ❓ Type of change\n\n<!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. -->\n\n- [ ] 📖 Documentation (updates to the documentation, readme, or JSdoc annotations)\n- [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)\n- [ ] 👌 Enhancement (improving an existing functionality like performance)\n- [ ] ✨ New feature (a non-breaking change that adds functionality)\n- [ ] 🧹 Chore (updates to the build process or auxiliary tools and libraries)\n- [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)\n\n### 📚 Description\n\n<!-- Describe your changes in detail -->\n<!-- Why is this change required? What problem does it solve? -->\n<!-- If it resolves an open issue, please link to the issue here. For example \"Resolves #1337\" -->\n\n### 📝 Checklist\n\n<!-- Put an `x` in all the boxes that apply. -->\n<!-- If your change requires a documentation PR, please link it appropriately -->\n<!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->\n\n- [ ] I have linked an issue or discussion.\n- [ ] I have updated the documentation accordingly.\n"
  },
  {
    "path": ".github/agents/maintainer.agent.md",
    "content": "---\nname: Maintainer\ndescription: >\n  Nitro project maintainer agent. Handles bug fixes, feature implementation,\n  code review, and contributions following project conventions. Understands the\n  build system, runtime constraints, deployment presets, and testing strategy.\ntools:\n  - \"*\"\n---\n\nYou are a maintainer of the Nitro project. Follow all instructions in [AGENTS.md](../../AGENTS.md) strictly.\n\nFor deeper architectural context, refer to the `.agents/` directory:\n\n- `.agents/architecture.md` — Core architecture, build system, config resolution, virtual modules, runtime internals.\n- `.agents/presets.md` — Deployment presets, preset structure, resolution logic.\n- `.agents/testing.md` — Test structure, adding regression tests, running tests.\n- `.agents/vite.md` — Vite build system, plugin architecture, dev server, HMR.\n- `.agents/docs.md` — Documentation conventions, H3 v2 API patterns.\n\nH3 v2 docs are at `node_modules/h3/skills/h3/docs/TOC.md`.\n\n## Key principles\n\n- Prefer minimal, targeted changes over large refactors.\n- Code in `src/runtime/` must be runtime-agnostic (Web APIs, no Node.js-specific APIs).\n- Use `pathe` instead of `node:path`.\n- Use existing UnJS utilities (`defu`, `consola`, `unstorage`) before adding new packages.\n- Bug fixes MUST include a failing regression test first.\n- Always run `pnpm format` and `pnpm typecheck` after changes.\n- Use semantic commit messages with scope (e.g., `fix(runtime): ...`).\n"
  },
  {
    "path": ".github/codecov.yml",
    "content": "coverage:\n  status:\n    project:\n      default:\n        threshold: 50%\n"
  },
  {
    "path": ".github/copilot-instructions.md",
    "content": "@../AGENTS.md\n\nRefer to [AGENTS.md](../AGENTS.md) for project instructions.\n"
  },
  {
    "path": ".github/workflows/autofix.yml",
    "content": "name: autofix.ci # needed to securely identify the workflow\n\non:\n  pull_request:\n  push:\n    branches:\n      - main\n\npermissions:\n  contents: read\n\njobs:\n  autofix:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    steps:\n      - uses: actions/checkout@v6\n      - run: npm i -g --force corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with:\n          node-version: lts/*\n          cache: \"pnpm\"\n      - run: pnpm install\n      - run: pnpm stub\n      - run: pnpm gen-presets\n      - name: Fix lint issues\n        run: npm run format\n      - uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8\n        with:\n          commit-message: \"chore: apply automated updates\"\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: ci\n\non:\n  push: { branches: [main] }\n  pull_request: { branches: [main] }\n\njobs:\n  tests-checks:\n    runs-on: ${{ matrix.os }}\n    timeout-minutes: 10\n    strategy:\n      matrix:\n        os: [ubuntu-latest]\n\n    steps:\n      - uses: actions/checkout@v6\n      - run: npm i -g --force corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with: { node-version: lts/*, cache: pnpm }\n      - run: pnpm install\n      - run: pnpm stub && pnpm lint\n      - run: pnpm typecheck\n      - run: pnpm vitest run test/unit\n      - run: pnpm vitest run test/minimal\n  tests-rollup:\n    runs-on: ${{ matrix.os }}\n    timeout-minutes: 10\n    strategy:\n      matrix:\n        os: [ubuntu-latest, windows-latest]\n\n    steps:\n      - uses: actions/checkout@v6\n      - run: npm i -g --force corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with: { node-version: lts/*, cache: pnpm }\n      - uses: oven-sh/setup-bun@v2\n        if: ${{ matrix.os != 'windows-latest' }}\n        with: { bun-version: latest }\n      - uses: denoland/setup-deno@v1\n        if: ${{ matrix.os != 'windows-latest' }}\n        with: { deno-version: 2.7.4 }\n      - run: node scripts/vite7.ts\n      - run: pnpm install\n      - run: pnpm stub && pnpm lint\n        if: ${{ matrix.os != 'windows-latest' }}\n      - run: pnpm build\n      - run: pnpm vitest run test/examples\n        env: { NITRO_BUILDER: rollup, NITRO_VITE_PKG: vite7 }\n      - run: pnpm vitest run test/presets\n        env: { NITRO_BUILDER: rollup, NITRO_VITE_PKG: vite7 }\n\n  tests-rolldown:\n    runs-on: ${{ matrix.os }}\n    timeout-minutes: 10\n    strategy:\n      matrix:\n        os: [ubuntu-latest, windows-latest]\n\n    steps:\n      - uses: actions/checkout@v6\n      - run: npm i -g --force corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with: { node-version: lts/*, cache: pnpm }\n      - uses: oven-sh/setup-bun@v2\n        if: ${{ matrix.os != 'windows-latest' }}\n        with: { bun-version: latest }\n      - uses: denoland/setup-deno@v1\n        if: ${{ matrix.os != 'windows-latest' }}\n        with: { deno-version: 2.7.4 }\n      - run: pnpm install\n      - run: pnpm build\n      - run: pnpm vitest run test/examples\n        env: { NITRO_BUILDER: rolldown, NITRO_VITE_PKG: vite }\n      - run: pnpm vitest run test/presets\n        env: { NITRO_BUILDER: rolldown, NITRO_VITE_PKG: vite }\n  publish-pkg-pr-new:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    needs: [tests-checks, tests-rollup, tests-rolldown]\n    steps:\n      - uses: actions/checkout@v6\n        with: { fetch-depth: 0 }\n      - run: npm i -fg corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with: { node-version: lts/*, cache: \"pnpm\" }\n      - run: pnpm install\n      - run: pnpm build\n      - run: pnpm dlx pkg-pr-new publish || true\n  publish-nitro-nightly:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    environment: npm-publish-nightly\n    permissions: { id-token: write, contents: read }\n    needs: [tests-checks, tests-rollup, tests-rolldown]\n    if: contains('refs/heads/main', github.ref) && github.event_name == 'push'\n    steps:\n      - uses: actions/checkout@v6\n        with: { fetch-depth: 0 }\n      - run: npm i -fg corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with: { node-version: lts/*, cache: \"pnpm\" }\n      - run: pnpm install\n      - run: pnpm build\n      - run: pnpm changelogen --bump -r 3.0.1 --canary nightly\n      - run: npm i -g npm@latest && npm publish --tag latest\n"
  },
  {
    "path": ".github/workflows/copilot-setup-steps.yml",
    "content": "name: \"Copilot Setup Steps\"\n\non: workflow_dispatch\n\njobs:\n  copilot-setup-steps:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n    steps:\n      - uses: actions/checkout@v6\n      - run: npm i -g --force corepack && corepack enable\n      - uses: actions/setup-node@v6\n        with: { node-version: lts/*, cache: pnpm }\n      - run: pnpm install\n      - run: pnpm build --stub\n"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "content": "name: npm-publish\n\non:\n  push:\n    tags:\n      - \"v*\"\n\npermissions: {}\n\njobs:\n  publish:\n    name: Publish to npm\n    runs-on: ubuntu-latest\n    if: github.repository == 'nitrojs/nitro'\n    timeout-minutes: 30\n    environment: npm-publish\n    permissions:\n      contents: write\n      id-token: write\n\n    steps:\n      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2\n        with:\n          fetch-depth: 0\n\n      - run: npm i -g --force corepack && corepack enable\n\n      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0\n        with:\n          node-version: lts/*\n          cache: pnpm\n          registry-url: https://registry.npmjs.org\n\n      - run: pnpm install\n      - run: pnpm build\n      - run: pnpm lint\n      - run: pnpm typecheck\n      - run: pnpm test:rolldown\n\n      - name: Publish to npm with provenance\n        # Uses OIDC trusted publishing — no NPM_TOKEN needed.\n        run: npm publish --provenance --access public --tag latest\n\n      - name: Create GitHub Release\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          TAG: ${{ github.ref_name }}\n        run: |\n          gh release create \"$TAG\" \\\n            --notes \"$(pnpm changelogen --from=$(git describe --tags --abbrev=0 \"$TAG^\"))\" \\\n            --title \"$TAG\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# Dependencies\nnode_modules\njspm_packages\n\n# Nitro\nnitro.d.ts\n.nitro\n.data\n\npackage-lock.json\n\n# Logs\n*.log\n\n# Temp directories\n.temp\n.tmp\n.cache\n\n# Generated dirs\ndist\n.nuxt\n.output\n.gen\n.tmp\nnuxt.d.ts\n\n# Junit reports\nreports\n\n# Coverage reports\ncoverage\n*.lcov\n.nyc_output\n\n# VSCode\n.vscode\n\n# Intellij idea\n*.iml\n.idea\n\n# OSX\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n.vercel_build_output\n.build-*\n.env\n.netlify\n.vercel\n.amplify-hosting\nstaticwebapp.config.json\nplayground/firebase.json\n.zeabur\n.apphosting\n\ntest/fixture/functions\n.data\n\n.pnpm-store\n.wrangler\n\nCHANGELOG.md\nRELEASE_NOTES.md\nskills/nitro/docs\n"
  },
  {
    "path": ".nvmrc",
    "content": "lts/*\n"
  },
  {
    "path": ".oxfmtrc.json",
    "content": "{\n  \"$schema\": \"./node_modules/oxfmt/configuration_schema.json\",\n  \"trailingComma\": \"es5\",\n  \"ignorePatterns\": [\"*.md\", \"pnpm*.yaml\", \"**/*.gen.ts\", \"**/.docs\", \"**/dist/**\"]\n}\n"
  },
  {
    "path": ".oxlintrc.json",
    "content": "{\n  \"$schema\": \"./node_modules/oxlint/configuration_schema.json\",\n  \"plugins\": [\"unicorn\", \"typescript\", \"oxc\"],\n  \"rules\": {\n    \"no-control-regex\": \"off\",\n    \"no-unused-expressions\": \"off\",\n    \"no-unused-vars\": \"off\",\n    \"typescript/no-useless-empty-export\": \"off\",\n    \"unicorn/no-empty-file\": \"off\",\n    \"unicorn/no-invalid-fetch-options\": \"off\",\n    \"unicorn/no-useless-spread\": \"off\"\n  }\n}\n"
  },
  {
    "path": "AGENTS.md",
    "content": "## Project Identity\n\nNitro is a framework-agnostic and deployment-agnostic server framework powered by [H3](https://github.com/h3js/h3) (v2), [UnJS] (https://github.com/unjs), and Vite | Rolldown | Rollup.\n\n## First-time Setup for Development\n\n- Run `corepack enable` to ensure `pnpm` is available.\n- Run `pnpm install` to install dependencies.\n- Run `pnpm build --stub` to prepare development mode.\n\n## Key Scripts\n\n- `pnpm build --stub` — Fast stub build for development.\n- `pnpm lint` — Lint and format code.\n- `pnpm format` — Automatically fix lint and formatting issues.\n- `pnpm test` — Run all tests.\n- `pnpm typecheck` — Run type tests.\n\n**Always run** `pnpm format` and `pnpm typecheck` after making changes.\n\n## Repository Structure\n\n- `.github/` — GitHub Actions workflows.\n- `docs/` — Documentation site built with [UnDocs](https://github.com/unjs/undocs).\n- `examples/` — Example projects and integrations.\n- `src/` — Project source code.\n- `test/` — Unit, minimal, and end-to-end tests.\n\n### Code Structure\n\nProject source is centralized under `src/`:\n\n- `src/build` — Build logic (Vite | Rolldown | Rollup config, virtual templates, plugins).\n- `src/cli` — `nitro` CLI subcommands (each file in `src/cli/commands` is a command).\n- `src/config/` — Config defaults (`src/config/defaults.ts`) and resolvers/normalizers (`src/config/resolvers`).\n- `src/dev` and `src/runner` — Development server logic.\n- `src/prerender` — Prerender logic.\n- `src/presets` — Deployment presets and runtime entry.\n- `src/types` — Shared types.\n- `src/utils` — Internal utilities.\n- `src/runtime` — Runtime code that goes into the bundle (runtime and platform agnostic).\n\n### Why Changes in `src/` Are High-Impact\n\nCode in `src/` affects all Nitro users:\n\n- Changes in `src/runtime` are bundled and run across all deployment targets.\n- Changes in `src/build` affect build output and performance.\n- Changes in `src/presets` affect specific deployment platforms.\n- Changes in `src/config` affect default behavior.\n\nReview these changes carefully for backwards compatibility, bundle size, and cross-runtime support.\n\n## Code Patterns & Conventions\n\n- `pathe` — Cross-platform path operations (always prefer over `node:path`).\n- `defu` — Deep object merging and config defaults.\n- `consola` — Logging in build/dev code (use `nitro.logger` when available).\n- `unstorage` — Storage abstraction.\n\n### Runtime Constraints\n\nCode in `src/runtime/` must be runtime-agnostic:\n\n- **Don't use Node.js-specific APIs** (unless behind runtime checks).\n- Prefer **Web APIs** (fetch, Request, Response, URL, etc.).\n- Only use `console` for logging (no `consola` in runtime).\n- Keep bundle size minimal and side-effect free.\n\n## Testing Strategy\n\n### Test Structure\n\nMain tests are defined in `test/tests.ts` and setup per each deployment provider in `test/presets` and run against `test/fixture` nitro app. Add new regression tests to `test/fixture`.\n\nOther tests:\n\n- **Unit** (`test/unit/`) — Isolated unit tests.\n- **Minimal** (`test/minimal/`) — Smallest bundle output.\n\n### Testing Requirements\n\n- Run `pnpm run test` before submitting.\n- **Bug fixes MUST include a failing test first** — add regression tests to `test/fixture/` and make sure test script fails before attempting the fix and resolves after.\n- Keep tests deterministic and environment-independent.\n\n## Working with Presets\n\nEach preset in `src/presets/` defines deployment target behavior:\n\n- Runtime logic and entry is in `src/presets/<name>/runtime`\n- Preset config and utils (build time) are in `src/presets/<name>/*.ts`.\n\n## Development Workflow\n\n### Making Changes\n\n1. Make changes in `src/`.\n2. Run `pnpm build --stub` if you changed build logic.\n3. Test with `pnpm test`.\n4. Run `pnpm format`.\n5. Run `pnpm typecheck`.\n6. Run `pnpm vitest run`.\n\n## Contribution Principles\n\n- Prefer **minimal, targeted changes** over large refactors.\n- Avoid introducing new dependencies unless strictly necessary.\n  Add them to `devDependencies` unless they are required in runtime logic.\n- Be mindful of **bundle size**, startup cost, and runtime overhead.\n- Maintain **backwards compatibility** unless explicitly instructed otherwise.\n- Batch multiple related edits together. Avoid sequential micro-changes.\n- Never modify files outside the scope of the requested change.\n\n## Common Gotchas\n\n- **Don't use Node.js-specific APIs in `src/runtime/`** — Code runs in multiple runtimes (Node, workers, edge).\n- **Virtual modules must be registered** in `src/build/virtual.ts`.\n- **CLI commands** are in `src/cli/commands/` — Each file exports a command definition.\n- **Runtime size matters** — Check bundle impact with `pnpm build`.\n- **Use `pathe` not `node:path`** — Ensures cross-platform compatibility.\n\n## Error & Logging Guidelines\n\n- Prefer explicit errors over silent failures.\n- Use `nitro.logger` in build/dev code, `consola` as fallback.\n- Use `console` only in `src/runtime/` code.\n- Use warnings for recoverable situations; throw for invalid states.\n- Include actionable context in error messages.\n\n## Documentation Requirements\n\n- Update `docs/` for user-facing changes.\n- Update types and JSDoc for API changes.\n- Examples in `examples/` should reflect best practices and be added for new integrations.\n- Add migration notes for breaking changes.\n\n## Code Conventions\n\n- Use **ESM** and modern JavaScript; use explicit extensions (`.ts`, `.mjs`) in imports.\n- For `.json` imports, use `with { \"type\": \"json\" }`.\n- Avoid barrel files (`index.ts` re-exports); import directly from specific modules.\n- Place non-exported/internal helpers at the end of the file.\n- For multi-arg functions, use an options object as the second parameter.\n- Split logic across files; avoid long single-file modules (>200 LoC). Use `_*` prefix for internal files.\n- Prefer **Web APIs** over Node.js APIs where possible.\n- Do not add comments explaining what the line does unless prompted.\n- Before adding new code, study surrounding patterns, naming conventions, and architectural decisions.\n- Use existing UnJS utilities and dependencies before adding new packages.\n- Keep runtime code minimal and fast.\n\n## Commit Conventions\n\n- Use **semantic commit messages**, lower-case (e.g., `fix(cli): resolve path issue`).\n- Prefer to include scope (e.g., `feat(runtime):`, `fix(build):`).\n- Add a short description on the second line when helpful.\n\n## Detailed References\n\nFor deeper context, see `.agents/`:\n\n- [`.agents/architecture.md`](.agents/architecture.md) — Full architecture: core instance, build system, config resolution, virtual modules, runtime internals, dev server, routing, key libraries.\n- [`.agents/presets.md`](.agents/presets.md) — All 31 presets, preset structure, how to create presets, resolution logic.\n- [`.agents/testing.md`](.agents/testing.md) — Test structure, how tests work, adding regression tests, running tests.\n- [`.agents/vite.md`](.agents/vite.md) — Vite build system: plugin architecture (6 sub-plugins), environments API, dev server integration, production build stages, bundler config, HMR, runtime worker.\n- [`.agents/docs.md`](.agents/docs.md) — Documentation conventions: structure, preset naming (underscore), H3 v2 API patterns, import paths, common mistakes.\n\n- **Important:** H3 v2 updated docs is at `node_modules/h3/skills/h3/docs/TOC.md`\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "@AGENTS.md\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\nCODE_OF_CONDUCT.md.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contribution Guide\n\n<!-- https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/setting-guidelines-for-repository-contributors -->\n\n> All contributors lead the growth of Nitro - including you!\n\n## Discussions\n\nYou can involve in discussions using:\n\n- [GitHub Discussions](discussions)\n- [Nitro Discord](https://discord.nitro.build)\n\n## Contribute to the Code\n\n> [!IMPORTANT]\n> Please discuss your ideas with the maintainers before opening a pull request.\n\n### Local Development\n\n- Clone the [`nitrojs/nitro`](https://github.com/nitrojs/nitro) git repository.\n- Install the latest LTS version of [Node.js](https://nodejs.org/en/) (v22+).\n- Enable [corepack](https://github.com/nodejs/corepack) using `corepack enable` (run `npm i -g corepack` if it's not available).\n- Install dependencies using `pnpm install`.\n- Build the project in stub mode using `pnpm build --stub`.\n- Run the playground with `pnpm nitro dev ./playground` to verify changes.\n- Add, modify, and run tests using `pnpm test`.\n  - Tip: Run `pnpm vitest test/presets/node.test.ts` for quick testing.\n\n## Reporting Issues\n\nYou might encounter a bug while using Nitro.\n\nAlthough we aim to resolve all known issues, new bugs can emerge over time. Your bug report helps us find and fix them faster — even if you're unable to fix the underlying code yourself.\n\nHere’s how to report a bug effectively:\n\n### Ensure It's a Bug\n\nSometimes what seems like a bug may actually be expected behavior or a missing feature. Make sure you’re reporting an actual bug by creating a minimal nitro project and reducing scope.\n\n### Create a Minimal Reproduction\n\nPlease create a minimal reproduction using the Nitro starter templates.\n\nSometimes, bugs originate from another layer — not Nitro itself. A minimal reproduction helps identify the source and speeds up debugging.\n\nUse one of the following templates to reproduce the issue:\n\n- [Stackblitz Template](https://stackblitz.com/fork/github/nitrojs/starter)\n- [Nitro Starter Repo](https://github.com/nitrojs/starter)\n\nIf your bug involves a higher-level framework like [Nuxt](https://nuxt.com), please report it there. Maintainers will help narrow it down to a Nitro-level issue if needed.\n\n### Search Existing Issues and Discussions\n\nBefore creating a new issue, search existing [issues](https://github.com/nitrojs/nitro/issues) and [discussions](https://github.com/nitrojs/nitro/discussions) to see if your bug has already been reported.\n\nIf it has already been reported:\n- Add a 👍 reaction to the original post (instead of commenting \"me too\" or \"when will it be fixed\").\n- If you can provide additional context or a better/smaller reproduction, please share it.\n\n> [!NOTE]\n> If the issue seems related but different or old or already closed, it's **better to open a new issue**. Maintainers will merge similar issues if needed.\n\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) Pooya Parsa <pooya@pi0.io> and Nitro contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n## Third-Party Licenses\n\nThis software includes bundled third-party dependencies. The licenses and\ncopyright notices for these dependencies are available in\n`dist/THIRD-PARTY-LICENSES.md` within the distributed package.\n"
  },
  {
    "path": "README.md",
    "content": "[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/nitrojs/nitro)\n\n# Nitro\n\n> [!NOTE]\n> You’re viewing the **v3** branch.\n> For the current stable release, see [Nitro v2](https://github.com/nitrojs/nitro/tree/v2).\n\n**Nitro** extends your Vite app with a **production-ready server**, designed to run **anywhere**.\nAdd server routes, deploy across multiple platforms, and enjoy a **zero-config** experience.\n\n📘 **Docs:** [https://nitro.build](https://nitro.build)\n\n## Contributing\n\nSee Check out the [Contribution Guide](./CONTRIBUTING.md) to get started.\n\n## License\n\nReleased under the [MIT License](LICENSE).\n"
  },
  {
    "path": "automd.config.ts",
    "content": "import type { Config } from \"automd\";\nimport { readdir, stat, readFile } from \"node:fs/promises\";\nimport { join, extname, relative } from \"pathe\";\n\ninterface FileEntry {\n  path: string;\n  relativePath: string;\n  content: string;\n  language: string;\n}\n\nconst DEFAULT_IGNORE = [\n  \"node_modules\",\n  \".git\",\n  \".DS_Store\",\n  \".nuxt\",\n  \".output\",\n  \".nitro\",\n  \"dist\",\n  \"coverage\",\n  \".cache\",\n  \".turbo\",\n  \"pnpm-lock.yaml\",\n  \"package-lock.json\",\n  \"yarn.lock\",\n];\n\nconst EXTENSION_LANGUAGE_MAP: Record<string, string> = {\n  \".ts\": \"ts\",\n  \".tsx\": \"tsx\",\n  \".js\": \"js\",\n  \".jsx\": \"jsx\",\n  \".mjs\": \"js\",\n  \".cjs\": \"js\",\n  \".vue\": \"vue\",\n  \".json\": \"json\",\n  \".html\": \"html\",\n  \".css\": \"css\",\n  \".scss\": \"scss\",\n  \".md\": \"md\",\n  \".yaml\": \"yaml\",\n  \".yml\": \"yaml\",\n  \".toml\": \"toml\",\n  \".sh\": \"bash\",\n  \".bash\": \"bash\",\n  \".zsh\": \"bash\",\n};\n\nasync function parseGitignore(dir: string): Promise<string[]> {\n  try {\n    const gitignorePath = join(dir, \".gitignore\");\n    const content = await readFile(gitignorePath, \"utf8\");\n    return content\n      .split(\"\\n\")\n      .map((line) => line.trim())\n      .filter((line) => line && !line.startsWith(\"#\"));\n  } catch {\n    return [];\n  }\n}\n\nfunction shouldIgnore(name: string, ignorePatterns: string[], defaultIgnore: string[]): boolean {\n  const allPatterns = [...defaultIgnore, ...ignorePatterns];\n  for (const pattern of allPatterns) {\n    const cleanPattern = pattern.replace(/^\\//, \"\").replace(/\\/$/, \"\");\n    if (name === cleanPattern) {\n      return true;\n    }\n    if (pattern.startsWith(\"*\") && name.endsWith(pattern.slice(1))) {\n      return true;\n    }\n    if (pattern.endsWith(\"*\") && name.startsWith(pattern.slice(0, -1))) {\n      return true;\n    }\n  }\n  return false;\n}\n\nfunction getLanguage(filePath: string): string {\n  const ext = extname(filePath).toLowerCase();\n  return EXTENSION_LANGUAGE_MAP[ext] || \"text\";\n}\n\nasync function collectFiles(\n  dir: string,\n  baseDir: string,\n  ignorePatterns: string[],\n  maxDepth: number,\n  currentDepth: number = 0\n): Promise<FileEntry[]> {\n  if (maxDepth > 0 && currentDepth >= maxDepth) {\n    return [];\n  }\n\n  const entries = await readdir(dir);\n  const files: FileEntry[] = [];\n\n  for (const entry of entries) {\n    if (shouldIgnore(entry, ignorePatterns, DEFAULT_IGNORE)) {\n      continue;\n    }\n\n    const fullPath = join(dir, entry);\n    const stats = await stat(fullPath);\n\n    if (stats.isDirectory()) {\n      const nestedFiles = await collectFiles(\n        fullPath,\n        baseDir,\n        ignorePatterns,\n        maxDepth,\n        currentDepth + 1\n      );\n      files.push(...nestedFiles);\n    } else {\n      try {\n        const content = await readFile(fullPath, \"utf8\");\n        const relativePath = relative(baseDir, fullPath);\n        files.push({\n          path: fullPath,\n          relativePath,\n          content: content.trim(),\n          language: getLanguage(fullPath),\n        });\n      } catch {\n        // Skip binary or unreadable files\n      }\n    }\n  }\n\n  return files;\n}\n\nfunction sortFiles(files: FileEntry[]): FileEntry[] {\n  return files.sort((a, b) => {\n    const aParts = a.relativePath.split(\"/\");\n    const bParts = b.relativePath.split(\"/\");\n\n    // Sort by depth first (shallower files first)\n    if (aParts.length !== bParts.length) {\n      return aParts.length - bParts.length;\n    }\n\n    // Then alphabetically\n    return a.relativePath.localeCompare(b.relativePath);\n  });\n}\n\nfunction generateCodeTree(\n  files: FileEntry[],\n  options: { defaultValue?: string; expandAll?: boolean } = {}\n): string {\n  const sortedFiles = sortFiles(files);\n  const codeBlocks: string[] = [];\n\n  for (const file of sortedFiles) {\n    const lang = file.language;\n    const filename = file.relativePath;\n\n    // Use 4 backticks for markdown files to avoid conflicts\n    const fence = lang === \"md\" ? \"````\" : \"```\";\n    codeBlocks.push(`${fence}${lang} [${filename}]`);\n    codeBlocks.push(file.content);\n    codeBlocks.push(fence);\n    codeBlocks.push(\"\");\n  }\n\n  const attrs: string[] = [];\n  if (options.defaultValue) {\n    attrs.push(`defaultValue=\"${options.defaultValue}\"`);\n  }\n  if (options.expandAll) {\n    attrs.push(`expandAll`);\n  }\n  const propsStr = attrs.length > 0 ? `{${attrs.join(\" \")}}` : \"\";\n  const contents = `::code-tree${propsStr}\\n\\n${codeBlocks.join(\"\\n\").trim()}\\n\\n::`;\n\n  return contents;\n}\n\nfunction resolvePath(srcPath: string, options: { url?: string; dir?: string }): string {\n  if (srcPath.startsWith(\"/\")) {\n    return srcPath;\n  }\n  const base = options.url ? new URL(\".\", options.url).pathname : options.dir || process.cwd();\n  return join(base, srcPath);\n}\n\nexport default {\n  input: [\"README.md\", \"docs/**/*.md\"],\n  generators: {\n    compatDate: {\n      name: \"compatDate\",\n      async generate(ctx) {\n        // const { compatibilityChanges } = await import(\"./lib/meta.mjs\");\n\n        // const table = [\n        //   \"| Compatibility date | Platform | Description |\",\n        //   \"|------|----------|-------------|\",\n        //   ...compatibilityChanges.map(\n        //     (change) =>\n        //       `| **≥ ${change.from}** | ${change.platform} | ${change.description} |`\n        //   ),\n        // ];\n        return {\n          // contents: table.join(\"\\n\"),\n          contents: \"\",\n        };\n      },\n    },\n    \"ui-code-tree\": {\n      name: \"ui-code-tree\",\n      async generate({\n        args,\n        config,\n        url,\n      }: {\n        args: Record<string, unknown>;\n        config: { dir?: string };\n        url?: string;\n      }) {\n        const srcPath = (args.src as string) || \".\";\n        const fullPath = resolvePath(srcPath, { url, dir: config.dir });\n\n        const stats = await stat(fullPath);\n        if (!stats.isDirectory()) {\n          throw new Error(`Path \"${srcPath}\" is not a directory`);\n        }\n\n        const userIgnore: string[] = args.ignore\n          ? String(args.ignore)\n              .split(\",\")\n              .map((s: string) => s.trim())\n          : [];\n\n        const gitignorePatterns = await parseGitignore(fullPath);\n        const ignorePatterns = [...gitignorePatterns, ...userIgnore, \"README.md\", \".*\"];\n\n        const maxDepth = args.maxDepth ? Number(args.maxDepth) : 0;\n        const defaultValue = (args.defaultValue || args.default) as string | undefined;\n        const expandAll = args.expandAll !== undefined && args.expandAll !== \"false\";\n\n        const files = await collectFiles(fullPath, fullPath, ignorePatterns, maxDepth);\n\n        if (files.length === 0) {\n          return {\n            contents: \"<!-- No files found -->\",\n            issues: [\"No files found in the specified directory\"],\n          };\n        }\n\n        const contents = generateCodeTree(files, { defaultValue, expandAll });\n\n        return { contents };\n      },\n    },\n  },\n} satisfies Config;\n"
  },
  {
    "path": "build.config.ts",
    "content": "import { defineBuildConfig } from \"obuild/config\";\n\nimport { resolveModulePath } from \"exsolve\";\nimport { traceNodeModules } from \"nf3\";\nimport { mkdir, readFile, rmdir, writeFile } from \"node:fs/promises\";\nimport type { CodeSplittingOptions } from \"rolldown\";\n\nconst isStub = process.argv.includes(\"--stub\");\n\nconst pkg = await import(\"./package.json\", { with: { type: \"json\" } }).then((r) => r.default || r);\n\nconst tracePkgs = [\n  \"cookie-es\", // used by azure runtime\n  \"croner\", // used by internal/task\n  \"defu\", // used by open-api runtime\n  \"destr\", // used by node-server and deno-server\n  \"get-port-please\", // used by dev server\n  \"rendu\", // used by HTML renderer template\n  \"scule\", // used by runtime config\n  \"source-map\", // used by dev error runtime\n  \"ufo\", // used by presets and runtime\n  \"unctx\", // used by internal/context\n  \"youch\", // used by error handler\n  \"youch-core\", // used by error handler\n];\n\nexport default defineBuildConfig({\n  entries: [\n    {\n      type: \"bundle\",\n      input: [\"src/builder.ts\", \"src/cli/index.ts\", \"src/types/index.ts\", \"src/vite.ts\"],\n    },\n    {\n      type: \"transform\",\n      input: \"src/runtime/\",\n      outDir: \"dist/runtime\",\n    },\n    {\n      type: \"transform\",\n      input: \"src/presets/\",\n      outDir: \"dist/presets\",\n      filter: (id) => id.includes(\"runtime/\"),\n      dts: false,\n    },\n  ],\n  hooks: {\n    rolldownConfig(config) {\n      config.platform = \"node\";\n\n      config.resolve ??= {};\n      config.resolve.alias ??= {};\n      Object.assign(config.resolve.alias, {\n        \"node-fetch-native/proxy\": \"node-fetch-native/native\",\n        \"node-fetch-native\": \"node-fetch-native/native\",\n      });\n\n      config.external ??= [];\n      (config.external as string[]).push(\n        \"nitro\",\n        ...Object.keys(pkg.exports || {}).map((key) => key.replace(/^./, \"nitro\")),\n        ...Object.keys(pkg.dependencies),\n        ...Object.keys(pkg.peerDependencies),\n        ...tracePkgs,\n        \"typescript\",\n        \"firebase-functions\",\n        \"@scalar/api-reference\",\n        \"get-port-please\",\n        \"cloudflare:workers\",\n        \"@cloudflare/workers-types\",\n        // unplugin deps\n        \"@rspack/core\",\n        \"@farmfe/core\",\n        \"webpack\",\n        \"unloader\"\n      );\n    },\n    rolldownOutput(config) {\n      (config.codeSplitting as CodeSplittingOptions).groups?.unshift(\n        {\n          test: /src[/\\\\]build[/\\\\](plugins|virtual|\\w+\\.ts)/,\n          name: \"_build/common\",\n        },\n        { test: /src[/\\\\](utils)[/\\\\]/, name: \"_chunks/utils\" }\n      );\n      config.chunkFileNames = (chunk) => {\n        if (chunk.name.startsWith(\"_\")) {\n          return `[name].mjs`;\n        }\n        if (chunk.name === \"rolldown-runtime\") {\n          return `_common.mjs`;\n        }\n        if (chunk.moduleIds.every((id) => id.includes(\"node_modules\"))) {\n          const pkgNames = [\n            ...new Set(\n              chunk.moduleIds\n                .map(\n                  (id) =>\n                    id.match(/.*[/\\\\]node_modules[/\\\\](?<package>@[^/\\\\]+[/\\\\][^/\\\\]+|[^/\\\\]+)/)\n                      ?.groups?.package\n                )\n                .filter(Boolean)\n                .map((name) => name!.split(/[/\\\\]/).pop()!)\n                .filter(Boolean)\n            ),\n          ].sort((a, b) => a.length - b.length);\n          let chunkName = \"\";\n          for (const name of pkgNames) {\n            const separator = chunkName ? \"+\" : \"\";\n            if ((chunkName + separator + name).length > 30) {\n              break;\n            }\n            chunkName += separator + name;\n          }\n          return `_libs/${chunkName || \"_\"}.mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /src[/\\\\]cli[/\\\\]/.test(id))) {\n          return `cli/_chunks/[name].mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /build[/\\\\]vite[/\\\\]/.test(id))) {\n          return `_build/vite.[name].mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /build[/\\\\]rolldown[/\\\\]/.test(id))) {\n          return `_build/rolldown.mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /build[/\\\\]rollup[/\\\\]|build[/\\\\]plugins/.test(id))) {\n          return `_build/rollup.mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /src[/\\\\]dev[/\\\\]|src[/\\\\]runtime/.test(id))) {\n          return `_dev.mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /src[/\\\\]presets/.test(id))) {\n          return `_presets.mjs`;\n        }\n        if (\n          chunk.moduleIds.every((id) => /src[/\\\\]build[/\\\\]|src[/\\\\]presets|src[/\\\\]utils/.test(id))\n        ) {\n          return `_build/shared.mjs`;\n        }\n        if (chunk.moduleIds.every((id) => /src[/\\\\](runner|dev|runtime)/.test(id))) {\n          return `_chunks/dev.mjs`;\n        }\n        return \"_chunks/nitro.mjs\";\n      };\n    },\n    async end() {\n      if (isStub) {\n        return;\n      }\n\n      // Bundle docs\n      const { DocsManager, DocsSourceFS, exportDocsToFS } = await import(\"mdzilla\");\n      const man = new DocsManager(new DocsSourceFS(\"./docs\"));\n      await man.load();\n      await rmdir(\"./skills/nitro/docs\").catch(() => {});\n      await mkdir(\"./skills/nitro/docs\", { recursive: true });\n      await exportDocsToFS(man, \"./skills/nitro/docs\", {\n        title: \"Nitro Documentation\",\n        tocFile: \"TOC.md\",\n        filter: (e: { entry: { path: string } }) => !e.entry.path.startsWith(\"/blog\"),\n      });\n\n      // Trace included dependencies\n      await traceNodeModules(\n        tracePkgs.map((pkg) => resolveModulePath(pkg)),\n        {\n          hooks: {\n            tracedPackages(packages) {\n              // Avoid tracing direct dependencies\n              const deps = new Set([\n                ...Object.keys(pkg.dependencies),\n                ...Object.keys(pkg.peerDependencies),\n              ]);\n              for (const dep of deps) {\n                delete packages[dep];\n              }\n            },\n          },\n        }\n      );\n\n      // Vite types\n      await writeFile(\n        \"dist/vite.d.mts\",\n        `import \"vite/client\";\\nimport \"nitro/vite/types\";\\n${await readFile(\"dist/vite.d.mts\", \"utf8\")}`\n      );\n    },\n  },\n});\n"
  },
  {
    "path": "changelog.config.ts",
    "content": "import type { ChangelogConfig } from \"changelogen\";\n\nexport default {\n  output: false,\n  types: {\n    presets: { title: \"Preset Changes\", semver: \"patch\" },\n  },\n} satisfies Partial<ChangelogConfig>;\n"
  },
  {
    "path": "docs/.config/automd.config.ts",
    "content": "export { default } from \"../../automd.config\";\n"
  },
  {
    "path": "docs/.config/docs.yaml",
    "content": "# yaml-language-server: $schema=https://unpkg.com/undocs/schema/config.json\nname: Nitro\nshortDescription: Ship Full-stack Vite Apps\ndescription: Add server API routes to any Vite apps and deploy with zero configuration on your favorite hosting platform.\ngithub: nitrojs/nitro\nurl: https://nitro.build\nsocials:\n  x: \"https://x.com/nitrojsdev\"\n  bluesky: \"https://bsky.app/profile/nitro.build\"\n  discord: https://discord.nitro.build\nsponsors:\n  api: https://sponsors.pi0.io/sponsors.json\nredirects:\n  # v2 guide → v3 docs\n  \"/guide\": \"/docs\"\n  \"/guide/getting-started\": \"/docs\"\n  \"/guide/utils\": \"/docs/routing\"\n  \"/guide/routing\": \"/docs/routing\"\n  \"/guide/websocket\": \"/docs/routing\"\n  \"/guide/cache\": \"/docs/cache\"\n  \"/guide/storage\": \"/docs/storage\"\n  \"/guide/database\": \"/docs/database\"\n  \"/guide/fetch\": \"/docs/routing\"\n  \"/guide/assets\": \"/docs/assets\"\n  \"/guide/plugins\": \"/docs/plugins\"\n  \"/guide/configuration\": \"/docs/configuration\"\n  \"/guide/typescript\": \"/docs/configuration\"\n  \"/guide/tasks\": \"/docs/tasks\"\n  \"/guide/nightly\": \"/docs/nightly\"\n  # v2 deploy\n  \"/deploy/workers\": \"/deploy\"\n  \"/deploy/runtimes/winterjs\": \"/deploy\"\n  \"/deploy/custom-presets\": \"/deploy\"\n  \"/deploy/providers/edgio\": \"/deploy\"\n  \"/deploy/node\": \"/deploy/runtimes/node\"\nthemeColor: \"rose\"\nautomd: true\nbranch: main\nversions:\n  - label: \"v3 (beta)\"\n    active: true\n  - label: \"v2 (legacy)\"\n    to: \"https://v2.nitro.build\"\n"
  },
  {
    "path": "docs/.docs/app.config.ts",
    "content": "import { defineAppConfig } from \"#imports\"\n\nexport default defineAppConfig({\n  ui: {\n    button: {\n      slots: {\n        base: 'active:translate-y-px transition-transform duration-300',\n      },\n    },\n  },\n})\n"
  },
  {
    "path": "docs/.docs/assets/css/main.css",
    "content": ":root {\n  --font-sans: \"Geist\", sans-serif !important;\n  --font-mono: \"Geist Mono\", monospace !important;\n}\n\nh1[data-slot=\"title\"] {\n  font-family: \"Geist Pixels\", sans-serif !important;\n}\n\n.landing-code {\n  --ui-bg-muted: #0c0c0e;\n  --ui-border-muted: #27272a;\n  --ui-bg: #0c0c0e;\n}\n\n.landing-code pre[style] {\n  background-color: #0c0c0e !important;\n}\n\n.landing-code > div > div {\n  margin-top: 0;\n  margin-bottom: 0;\n}\n"
  },
  {
    "path": "docs/.docs/components/AppHero.vue",
    "content": "<script setup lang=\"ts\">\ndefineProps<{\n  title: string\n  description: string\n  primaryLink: string\n  primaryLabel: string\n  githubLink: string\n  codeGroups: {\n    filename: string\n    code: string\n  }[]\n}>()\n</script>\n\n<template>\n  <UPageHero orientation=\"horizontal\">\n    <template #default>\n      <div class=\"code-group\">\n        <ProseCodeGroup>\n          <ProsePre\n            v-for=\"group in codeGroups\"\n            :key=\"group.filename\"\n            :filename=\"group.filename\"\n            language=\"ts\"\n          >\n            <pre>{{ group.code }}</pre>\n          </ProsePre>\n        </ProseCodeGroup>\n      </div>\n    </template>\n\n    <HeroBackground />\n\n    <template #title>\n      <span v-html=\"title\" />\n    </template>\n\n    <template #description>\n      {{ description }}\n    </template>\n\n    <template #links>\n      <UButton\n        size=\"xl\"\n        :to=\"primaryLink\"\n        trailing-icon=\"i-lucide-arrow-right\"\n      >\n        {{ primaryLabel }}\n      </UButton>\n      <UButton\n        color=\"neutral\"\n        icon=\"i-simple-icons-github\"\n        size=\"xl\"\n        target=\"_blank\"\n        :to=\"githubLink\"\n        variant=\"outline\"\n      >\n        GitHub\n      </UButton>\n    </template>\n  </UPageHero>\n</template>\n"
  },
  {
    "path": "docs/.docs/components/AppHeroLinks.vue",
    "content": "<template>\n  <div class=\"flex flex-wrap items-center justify-center gap-4\">\n    <UButton\n      size=\"xl\"\n      to=\"/docs/quick-start\"\n      trailing-icon=\"i-lucide-arrow-right\"\n    >\n      Get started\n    </UButton>\n    <UButton\n      color=\"neutral\"\n      icon=\"i-simple-icons-github\"\n      size=\"xl\"\n      target=\"_blank\"\n      to=\"https://github.com/nitrojs/nitro\"\n      variant=\"outline\"\n    >\n      Star on GitHub\n    </UButton>\n    <a\n      :href=\"`${baseURL}llms.txt`\"\n      target=\"_blank\"\n      class=\"basis-full text-sm text-muted hover:text-default transition-colors inline-flex items-center justify-center gap-1\"\n      @click.prevent=\"copyPrompt\"\n    >\n      <UIcon :name=\"copied ? 'i-lucide-clipboard-check' : 'i-lucide-bot'\" />\n      Docs for AI\n    </a>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nconst copied = ref(false)\nconst baseURL = computed(() => {\n  if (import.meta.client) {\n    return `${window.location.origin}/`\n  }\n  return '/'\n})\n\nfunction copyPrompt() {\n  const text = `Read nitro docs from ${baseURL.value}docs/quick-start so I can ask questions about it.`\n  navigator.clipboard.writeText(text)\n  copied.value = true\n  setTimeout(() => {\n    copied.value = false\n  }, 2000)\n}\n</script>\n"
  },
  {
    "path": "docs/.docs/components/FeatureCard.vue",
    "content": "<script setup lang=\"ts\">\nimport { Motion } from 'motion-v'\n\ndefineProps<{\n  headline?: string\n  link?: string\n  linkLabel?: string\n}>()\n\nconst prefersReducedMotion = ref(false)\n\nonMounted(() => {\n  prefersReducedMotion.value = window.matchMedia('(prefers-reduced-motion: reduce)').matches\n})\n</script>\n\n<template>\n  <Motion\n    :initial=\"prefersReducedMotion ? { opacity: 1 } : { opacity: 0, y: 20 }\"\n    :while-in-view=\"{ opacity: 1, y: 0 }\"\n    :transition=\"{ duration: 0.5 }\"\n    :in-view-options=\"{ once: true }\"\n  >\n    <NuxtLink :to=\"link\" class=\"block h-full\" :class=\"link ? 'cursor-pointer' : 'cursor-default'\">\n      <div class=\"relative overflow-hidden rounded-xl border border-default bg-white/60 dark:bg-neutral-900/60 backdrop-blur-sm p-8 h-full transition-all duration-300 hover:shadow-lg hover:-translate-y-1\">\n        <div v-if=\"headline\" class=\"text-xs font-mono uppercase tracking-widest text-primary mb-4 flex items-center gap-2\">\n          <span class=\"inline-block w-1 h-1 rounded-full bg-primary\" />\n          {{ headline }}\n        </div>\n\n        <h3 class=\"text-2xl font-bold text-neutral-900 dark:text-white mb-3 tracking-tight\">\n          <slot name=\"title\" />\n        </h3>\n\n        <p class=\"text-neutral-500 dark:text-neutral-400 text-sm leading-relaxed mb-6\">\n          <slot name=\"description\" />\n        </p>\n\n        <slot name=\"demo\" />\n\n        <span\n          v-if=\"link\"\n          class=\"inline-flex items-center gap-1 text-sm text-primary mt-auto\"\n        >\n          {{ linkLabel || 'Learn more' }}\n          <UIcon name=\"i-lucide-arrow-right\" class=\"size-4\" />\n        </span>\n      </div>\n    </NuxtLink>\n  </Motion>\n</template>\n"
  },
  {
    "path": "docs/.docs/components/HeroBackground.client.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, onMounted, defineAsyncComponent } from 'vue'\n\nconst Shader = defineAsyncComponent(() => import('shaders/vue').then(m => m.Shader))\nconst ChromaFlow = defineAsyncComponent(() => import('shaders/vue').then(m => m.ChromaFlow))\n\nconst enabled = ref(false)\n\nonMounted(() => {\n  const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent) || window.innerWidth < 768\n  const hasWebGPU = 'gpu' in navigator\n  const lowMemory = (navigator as any).deviceMemory !== undefined && (navigator as any).deviceMemory < 4\n  const lowCores = navigator.hardwareConcurrency !== undefined && navigator.hardwareConcurrency < 4\n\n  enabled.value = hasWebGPU && !isMobile && !lowMemory && !lowCores\n})\n</script>\n\n<template>\n  <Shader v-if=\"enabled\" class=\"absolute inset-0 w-full h-full -z-10\">\n    <ChromaFlow\n      base-color=\"oklch(71.2% 0.194 13.428)\"\n      up-color=\"oklch(70.2% 0.183 293.541)\"\n      down-color=\"oklch(70.2% 0.183 293.541)\"\n      right-color=\"oklch(70.2% 0.183 293.541)\"\n      left-color=\"oklch(70.2% 0.183 293.541)\"\n      :opacity=\"0.5\"\n      :intensity=\"0.7\"\n    />\n  </Shader>\n</template>\n"
  },
  {
    "path": "docs/.docs/components/HeroFeatures.vue",
    "content": "<script setup lang=\"ts\">\nimport { Motion } from 'motion-v'\n\nconst props = defineProps<{\n  features: {\n    title: string\n    description: string\n    icon: string\n    color: string\n    bgColor: string\n    borderColor: string\n  }[]\n}>()\n\nconst prefersReducedMotion = ref(false)\n\nfunction randomLines() {\n  const count = 2 + Math.floor(Math.random() * 3)\n  return Array.from({ length: count }, (_, j) => ({\n    width: `${20 + Math.floor(Math.random() * 80)}%`,\n    delay: j * 0.1,\n  }))\n}\n\nconst featureLines = computed(() => props.features.map(() => randomLines()))\n\nonMounted(() => {\n  prefersReducedMotion.value = window.matchMedia('(prefers-reduced-motion: reduce)').matches\n})\n</script>\n\n<template>\n  <section class=\"relative bg-neutral-50 dark:bg-neutral-950/30 py-14 border-y border-default\">\n    <UContainer>\n      <div class=\"grid md:grid-cols-3 gap-6\">\n        <Motion\n          v-for=\"(feature, i) in features\"\n          :key=\"feature.title\"\n          :initial=\"prefersReducedMotion ? { opacity: 1 } : { opacity: 0, y: 16 }\"\n          :while-in-view=\"{ opacity: 1, y: 0 }\"\n          :transition=\"{ duration: 0.4, delay: i * 0.1 }\"\n          :in-view-options=\"{ once: true }\"\n        >\n          <div :class=\"['group relative rounded-xl border border-default bg-white/80 dark:bg-neutral-900/50 p-6 h-full transition-all duration-300 hover:shadow-md', feature.borderColor]\">\n            <div class=\"flex items-center gap-3 mb-3\">\n              <div :class=\"[feature.bgColor, 'w-9 h-9 rounded-lg flex items-center justify-center shrink-0']\">\n                <UIcon :name=\"feature.icon\" :class=\"[feature.color, 'text-lg']\" />\n              </div>\n              <h3 class=\"text-lg font-bold text-neutral-900 dark:text-white tracking-tight\">\n                {{ feature.title }}\n              </h3>\n            </div>\n\n            <p class=\"text-sm text-neutral-500 dark:text-neutral-400 leading-relaxed mb-4\">\n              {{ feature.description }}\n            </p>\n\n            <div class=\"flex flex-col gap-1.5\">\n              <Motion\n                v-for=\"(line, j) in featureLines[i]\"\n                :key=\"j\"\n                :initial=\"{ width: '0%', opacity: 0 }\"\n                :while-in-view=\"{ width: line.width, opacity: 1 }\"\n                :transition=\"{ duration: 0.8, delay: 0.3 + line.delay + i * 0.1 }\"\n                :in-view-options=\"{ once: true }\"\n              >\n                <div :class=\"[feature.bgColor, 'h-1 rounded-full']\" />\n              </Motion>\n            </div>\n          </div>\n        </Motion>\n      </div>\n    </UContainer>\n  </section>\n</template>\n"
  },
  {
    "path": "docs/.docs/components/LandingFeatures.vue",
    "content": "<template>\n  <section class=\"relative bg-neutral-50 dark:bg-neutral-950/30 py-20 md:py-28\">\n    <div class=\"absolute inset-0 dotted-bg\" />\n    <div class=\"relative max-w-6xl mx-auto px-6\">\n      <div class=\"grid md:grid-cols-2 lg:grid-cols-3 gap-6\">\n        <slot name=\"body\" />\n      </div>\n    </div>\n  </section>\n</template>\n\n<style scoped>\n.dotted-bg {\n  background-image: radial-gradient(circle, rgb(0 0 0 / 0.1) 1px, transparent 1px);\n  background-size: 20px 20px;\n}\n\n:root.dark .dotted-bg {\n  background-image: radial-gradient(circle, rgb(255 255 255 / 0.07) 1px, transparent 1px);\n}\n</style>\n"
  },
  {
    "path": "docs/.docs/components/PerformanceShowcase.vue",
    "content": "<script setup lang=\"ts\">\nimport { Motion } from 'motion-v'\n\ndefineProps<{\n  headline?: string\n  title?: string\n  metrics: {\n    label: string\n    value: string\n    unit: string\n    description: string\n    icon: string\n    color: string\n    bgColor: string\n    barWidth: string\n    barColor: string\n  }[]\n}>()\n\nconst prefersReducedMotion = ref(false)\n\nonMounted(() => {\n  prefersReducedMotion.value = window.matchMedia('(prefers-reduced-motion: reduce)').matches\n})\n</script>\n\n<template>\n  <section class=\"relative py-20 md:py-28\">\n    <UContainer>\n      <div class=\"text-center mb-14\">\n        <p class=\"text-xs font-mono uppercase tracking-widest text-primary mb-3 flex items-center justify-center gap-2\">\n          <span class=\"inline-block w-1 h-1 rounded-full bg-primary\" />\n          {{ headline || 'Performance' }}\n        </p>\n        <h2 class=\"text-3xl md:text-4xl font-bold text-neutral-900 dark:text-white tracking-tight\">\n          {{ title || 'Built for speed' }}\n        </h2>\n      </div>\n\n      <div class=\"grid sm:grid-cols-2 lg:grid-cols-4 gap-5\">\n        <Motion\n          v-for=\"(metric, i) in metrics\"\n          :key=\"metric.label\"\n          :initial=\"prefersReducedMotion ? { opacity: 1 } : { opacity: 0, y: 24 }\"\n          :while-in-view=\"{ opacity: 1, y: 0 }\"\n          :transition=\"{ duration: 0.5, delay: i * 0.1 }\"\n          :in-view-options=\"{ once: true }\"\n        >\n          <div class=\"relative overflow-hidden rounded-xl border border-default bg-white/60 dark:bg-neutral-900/60 backdrop-blur-sm p-6 h-full flex flex-col\">\n            <div :class=\"[metric.bgColor, 'w-10 h-10 rounded-lg flex items-center justify-center mb-4']\">\n              <UIcon :name=\"metric.icon\" :class=\"[metric.color, 'text-xl']\" />\n            </div>\n\n            <div class=\"flex items-baseline gap-1.5 mb-1\">\n              <span class=\"text-2xl font-bold text-neutral-900 dark:text-white font-mono\">{{ metric.value }}</span>\n              <span class=\"text-sm text-neutral-400 font-mono\">{{ metric.unit }}</span>\n            </div>\n\n            <p class=\"text-sm font-medium text-neutral-600 dark:text-neutral-300 mb-3\">\n              {{ metric.label }}\n            </p>\n\n            <p class=\"text-xs text-neutral-400 dark:text-neutral-500 mb-3 leading-relaxed\">\n              {{ metric.description }}\n            </p>\n\n            <div class=\"mt-auto\">\n              <div class=\"h-1.5 w-full rounded-full bg-neutral-100 dark:bg-neutral-800 overflow-hidden\">\n                <Motion\n                  :initial=\"{ width: '0%' }\"\n                  :while-in-view=\"{ width: metric.barWidth }\"\n                  :transition=\"{ duration: 1, delay: 0.3 + i * 0.1 }\"\n                  :in-view-options=\"{ once: true }\"\n                >\n                  <div :class=\"[metric.barColor, 'h-full rounded-full']\" />\n                </Motion>\n              </div>\n            </div>\n          </div>\n        </Motion>\n      </div>\n    </UContainer>\n  </section>\n</template>\n"
  },
  {
    "path": "docs/.docs/layouts/examples.vue",
    "content": "<script setup lang=\"ts\">\nimport type { ContentNavigationItem } from '@nuxt/content'\nimport { categoryOrder } from '~/utils/examples'\n\n// Fetch all examples and group by category\nconst { data: examples } = await useAsyncData('examples-nav', () =>\n  queryCollection('content')\n    .where('path', 'LIKE', '/examples/%')\n    .select('title', 'description', 'meta', 'path')\n    .all(),\n)\n\n// Group examples by category\nconst groupedExamples = computed(() => {\n  if (!examples.value) return []\n\n  const groups: Record<string, ContentNavigationItem[]> = {}\n\n  for (const example of examples.value) {\n    const category = (example.meta as Record<string, any>)?.category || 'Other'\n    if (!groups[category]) {\n      groups[category] = []\n    }\n    groups[category].push({\n      title: example.title,\n      path: example.path,\n    })\n  }\n\n  // Convert to navigation items with children, sorted by categoryOrder\n  const sortedEntries = Object.entries(groups).sort(([a], [b]) => {\n    const aIndex = categoryOrder.indexOf(a.toLowerCase())\n    const bIndex = categoryOrder.indexOf(b.toLowerCase())\n    if (aIndex === -1 && bIndex === -1) return a.localeCompare(b)\n    if (aIndex === -1) return 1\n    if (bIndex === -1) return -1\n    return aIndex - bIndex\n  })\n\n  return sortedEntries.map(([category, items]) => ({\n    title: category.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' '),\n    path: '',\n    children: items,\n  }))\n})\n\n// Flat list for navigation (no groups)\nconst flatExamples = computed(() => {\n  if (!examples.value) return []\n  return examples.value.map((example) => ({\n    title: example.title,\n    path: example.path,\n  }))\n})\n</script>\n\n<template>\n  <UContainer>\n    <UPage :ui=\"{ left: 'lg:col-span-2 pr-2 border-r border-default' }\">\n      <template #left>\n        <UPageAside>\n          <UPageAnchors\n            :links=\"[\n              { label: 'Docs', icon: 'i-lucide-book-open', to: '/docs' },\n              { label: 'Deploy', icon: 'ri:upload-cloud-2-line', to: '/deploy' },\n              { label: 'Config', icon: 'ri:settings-3-line', to: '/config' },\n              { label: 'Examples', icon: 'i-lucide-folder-code', to: '/examples', active: true },\n            ]\"\n          />\n          <USeparator type=\"dashed\" class=\"py-6\" />\n          <UContentNavigation\n            v-if=\"groupedExamples.length\"\n            :navigation=\"groupedExamples\"\n            :collapsible=\"false\"\n          />\n          <UContentNavigation\n            v-else-if=\"flatExamples.length\"\n            :navigation=\"flatExamples\"\n            :collapsible=\"false\"\n          />\n        </UPageAside>\n      </template>\n      <slot />\n    </UPage>\n  </UContainer>\n</template>\n"
  },
  {
    "path": "docs/.docs/nuxt.config.ts",
    "content": "import { defineNuxtConfig } from \"nuxt/config\"\n\nexport default defineNuxtConfig({\n  modules: ['motion-v/nuxt'],\n  css: ['~/assets/css/main.css'],\n  fonts: {\n    families: [\n      { name: 'Geist', weights: [400, 600, 700], global: true },\n      { name: 'Geist Mono', weights: [400, 600], global: true },\n      { name: \"Geist Pixels\", src: \"/assets/fonts/GeistPixel-Square.woff2\", weight: 500, global: true },\n    ],\n  },\n})\n"
  },
  {
    "path": "docs/.docs/pages/examples/[...slug].vue",
    "content": "<script setup lang=\"ts\">\nimport { kebabCase } from 'scule'\n\ndefinePageMeta({\n  layout: 'examples',\n})\n\nconst appConfig = useAppConfig()\nconst route = useRoute()\n\nconst { data: page } = await useAsyncData(kebabCase(route.path), () =>\n  queryCollection('content').path(route.path).first(),\n)\nif (!page.value) {\n  throw createError({\n    statusCode: 404,\n    statusMessage: 'Example not found',\n    message: `${route.path} does not exist`,\n    fatal: true,\n  })\n}\n\nconst { data: surround } = await useAsyncData(`${kebabCase(route.path)}-surround`, () =>\n  queryCollectionItemSurroundings('content', route.path, {\n    fields: ['description'],\n  }),\n)\n\n// Extract example name from route (e.g., \"/examples/vite-ssr-html\" -> \"vite-ssr-html\")\nconst exampleName = computed(() => {\n  return route.path.replace(/^\\/examples\\//, '')\n})\n\nconst breadcrumb = computed(() => [\n  { label: 'Examples', icon: 'i-lucide-folder-code', to: '/examples' },\n  { label: page.value?.title || exampleName.value },\n])\n\nusePageSEO({\n  title: `${page.value?.title} - ${appConfig.site.name}`,\n  ogTitle: page.value?.title,\n  description: page.value?.description,\n})\n\n</script>\n\n<template>\n  <UPage v-if=\"page\">\n    <UPageHeader\n      :title=\"page.title\"\n      :description=\"page.description\"\n      :ui=\"{\n        wrapper: 'flex-row items-center flex-wrap justify-between',\n      }\"\n    >\n      <template #headline>\n        <UBreadcrumb :items=\"breadcrumb\" />\n      </template>\n      <template #links>\n        <UButton\n          icon=\"i-simple-icons-stackblitz\"\n          label=\"Open in Playground\"\n          color=\"neutral\"\n          variant=\"soft\"\n          size=\"sm\"\n          :to=\"`https://stackblitz.com/fork/github/${appConfig.docs.github}/tree/${appConfig.docs.branch || 'main'}/examples/${exampleName}`\"\n          target=\"_blank\"\n        />\n\n        <UButton\n          icon=\"i-simple-icons-github\"\n          label=\"Source\"\n          color=\"neutral\"\n          variant=\"soft\"\n          size=\"sm\"\n          :to=\"`https://github.com/${appConfig.docs.github}/tree/${appConfig.docs.branch || 'main'}/examples/${exampleName}`\"\n          target=\"_blank\"\n        />\n\n        <PageHeaderLinks />\n      </template>\n    </UPageHeader>\n\n    <template v-if=\"page.body?.toc?.links?.length\" #right>\n      <UContentToc title=\"On this page\" :links=\"page.body?.toc?.links || []\" highlight />\n    </template>\n\n    <UPageBody prose class=\"break-words\">\n      <ContentRenderer v-if=\"page.body\" :value=\"page\" />\n\n      <div class=\"space-y-6\">\n        <USeparator type=\"dashed\" />\n        <div class=\"mb-4\">\n          <UPageLinks\n            class=\"inline-block\"\n            :links=\"[\n              {\n                icon: 'i-lucide-pencil',\n                label: 'Edit this page',\n                to: `https://github.com/${appConfig.docs.github}/edit/${appConfig.docs.branch || 'main'}/docs/4.examples/${exampleName}.md`,\n                target: '_blank',\n              },\n            ]\"\n          />\n        </div>\n        <UContentSurround v-if=\"surround?.length\" class=\"mb-4\" :surround=\"surround\" />\n      </div>\n    </UPageBody>\n  </UPage>\n</template>\n"
  },
  {
    "path": "docs/.docs/pages/examples/index.vue",
    "content": "<script setup lang=\"ts\">\nimport { categoryOrder, categoryIcons } from '~/utils/examples'\n\ndefinePageMeta({\n  layout: 'examples',\n})\n\nconst appConfig = useAppConfig()\n\n// Fetch all examples\nconst { data: examples } = await useAsyncData('examples-list', () =>\n  queryCollection('content')\n    .where('path', 'LIKE', '/examples/%')\n    .select('title', 'description', 'meta', 'path')\n    .all(),\n)\n\n// Group examples by category\nconst groupedExamples = computed(() => {\n  if (!examples.value) return {}\n\n  const groups: Record<string, typeof examples.value> = {}\n\n  for (const example of examples.value) {\n    const category = (example.meta as Record<string, any>)?.category || 'Other'\n    if (!groups[category]) {\n      groups[category] = []\n    }\n    groups[category].push(example)\n  }\n\n  // Sort groups by categoryOrder\n  const sortedEntries = Object.entries(groups).sort(([a], [b]) => {\n    const aIndex = categoryOrder.indexOf(a.toLowerCase())\n    const bIndex = categoryOrder.indexOf(b.toLowerCase())\n    if (aIndex === -1 && bIndex === -1) return a.localeCompare(b)\n    if (aIndex === -1) return 1\n    if (bIndex === -1) return -1\n    return aIndex - bIndex\n  })\n\n  return Object.fromEntries(sortedEntries)\n})\n\nusePageSEO({\n  title: `Examples - ${appConfig.site.name}`,\n  ogTitle: 'Examples',\n  description: 'Explore Nitro examples to learn how to build full-stack applications',\n})\n</script>\n\n<template>\n  <UPage>\n    <UPageHeader\n      title=\"Examples\"\n      description=\"Explore Nitro examples to learn how to build full-stack applications with different frameworks and features.\"\n    >\n      <template #headline>\n        <UBreadcrumb :items=\"[{ label: 'Examples', icon: 'i-lucide-code' }]\" />\n      </template>\n    </UPageHeader>\n\n    <UPageBody>\n      <div v-for=\"(categoryExamples, category) in groupedExamples\" :key=\"category\" class=\"mb-12\">\n        <h2 class=\"text-xl font-semibold mb-4 flex items-center gap-2\">\n          <UIcon :name=\"categoryIcons[String(category).toLowerCase()] || categoryIcons.other\" class=\"size-5\" />\n          {{ String(category).charAt(0).toUpperCase() + String(category).slice(1) }}\n        </h2>\n\n        <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n          <UPageCard\n            v-for=\"example in categoryExamples\"\n            :key=\"example.path\"\n            :to=\"example.path\"\n            :title=\"example.title\"\n            :description=\"example.description\"\n            :icon=\"(example.meta as any)?.icon\"\n          />\n        </div>\n      </div>\n\n      <div v-if=\"!examples?.length\" class=\"text-center py-12\">\n        <UIcon name=\"i-lucide-book-dashed\" class=\"size-12 text-muted mx-auto mb-4\" />\n        <p class=\"text-muted\">No examples</p>\n      </div>\n    </UPageBody>\n  </UPage>\n</template>\n"
  },
  {
    "path": "docs/.docs/pages/index.vue",
    "content": "<script setup lang=\"ts\">\nconst { data: page } = await useAsyncData('index', () => queryCollection('content').path('/').first())\nif (!page.value) {\n  throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })\n}\n\nconst title = page.value.seo?.title || page.value.title\nconst description = page.value.seo?.description || page.value.description\n\nusePageSEO({\n  title: title,\n  description: description,\n})\n</script>\n\n<template>\n  <ContentRenderer\n    v-if=\"page\"\n    :value=\"page\"\n    :prose=\"false\"\n  />\n</template>\n"
  },
  {
    "path": "docs/.docs/utils/examples.ts",
    "content": "// Category order for examples - used in sidebar and examples page\nexport const categoryOrder = [\n  'features',\n  'config',\n  'server side rendering',\n  'backend frameworks',\n  'integrations',\n  'vite',\n]\n\nexport const categoryIcons: Record<string, string> = {\n  vite: 'i-logos-vitejs',\n  'backend frameworks': 'i-lucide-puzzle',\n  features: 'i-lucide-sparkles',\n  config: 'i-lucide-settings',\n  integrations: 'i-lucide-plug',\n  'server side rendering': 'i-lucide-server',\n  other: 'i-lucide-folder',\n}\n"
  },
  {
    "path": "docs/.npmrc",
    "content": "shamefully-hoist=true\n"
  },
  {
    "path": "docs/1.docs/.navigation.yml",
    "content": "icon: i-lucide-book-open\n"
  },
  {
    "path": "docs/1.docs/1.index.md",
    "content": "---\nicon: i-lucide-compass\n---\n\n# Introduction\n\n> Nitro is a full-stack server framework, compatible with any runtime and any deployment target.\n\nNitro gives you a production-ready server with filesystem routing, code-splitting, and built-in support for storage, caching, and databases — all runtime-agnostic and deployable anywhere.\n\n## What is Nitro?\n\nCreate server and API routes inside the `routes/` directory. Each file maps directly to a URL path, and Nitro handles the rest — routing, code-splitting, and optimized builds.\n\nYou can also take full control of the server entry by creating a `server.ts` file. Nitro’s high-level, runtime-agnostic approach lets you use any HTTP library, such as [Elysia](https://elysiajs.com/), [h3](https://h3.dev), or [Hono](https://hono.dev).\n\n### Performance\n\nNitro compiles your routes at build time, removing the need for a runtime router. Only the code required to handle each incoming request is loaded and executed. This makes it ideal for serverless hosting, with near-0ms boot time regardless of project size.\n\n### Deploy Anywhere\n\nBuild your server into an optimized `.output/` folder compatible with Node.js, Bun, Deno, and many hosting platforms without any configuration — Cloudflare Workers, Netlify, Vercel, and more. Take advantage of platform features like ESR, ISR, and SWR without changing a single line of code.\n\n### Server-Side Rendering\n\nRender HTML with your favorite templating engine, or use component libraries such as React, Vue, or Svelte directly on the server. Go full universal rendering with client-side hydration. Nitro provides the foundation and a progressive approach to reach your goals.\n\n### Storage\n\nNitro includes a runtime-agnostic key-value storage layer out of the box. It uses in-memory storage by default, but you can connect more than 20 different drivers (FS, Redis, S3, etc.), attach them to different namespaces, and swap them without changing your code.\n\n### Caching\n\nNitro supports caching for both server routes and server functions, backed directly by the server storage (via the `cache` namespace).\n\n### Database\n\nNitro also includes a built-in SQL database. It defaults to SQLite, but you can connect to and query more than 10 databases (Postgres, MySQL, PGLite, etc.) using the same API.\n\n### Meta-Framework Foundation\n\nNitro can be used as the foundation for building your own meta-framework. Popular frameworks such as Nuxt, SolidStart, and TanStack Start fully or partially leverage Nitro.\n\n## Vite Integration\n\nNitro integrates seamlessly with [Vite](https://vite.dev) as a plugin. If you’re building a frontend application with Vite, adding Nitro gives you API routes, server-side rendering, and a full production server — all built together with `vite build`.\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n```\n\nWith Nitro, `vite build` produces an optimized `.output/` folder containing both your frontend and backend — ready to deploy anywhere.\n\nReady to give it a try? Jump into the [quick start](/docs/quick-start).\n"
  },
  {
    "path": "docs/1.docs/2.quick-start.md",
    "content": "---\nicon: i-lucide-zap\n---\n\n# Quick Start\n\n> Start with a fresh Nitro project or adopt it in your current Vite project.\n\n## Try Nitro online\n\nGet a taste of Nitro in your browser using our playground.\n\n[Play with Nitro in StackBlitz](https://stackblitz.com/github/nitrojs/starter/tree/v3-vite?file=index.html,server.ts){target=\"_blank\"}\n\n\n## Create a Nitro project\n\nThe fastest way to create a Nitro application is using the `create-nitro-app`.\n\n> [!NOTE]\n> Make sure to have installed the latest LTS version of either [Node.js](https://nodejs.org/en), [Bun](https://bun.sh/), or [Deno](https://deno.com/).\n\n:pm-x{command=\"create-nitro-app\"}\n\n<details>\n  <summary>Preview</summary>\n  <div style=\"display:flex;justify-content:center;\">\n    <img src=\"https://github.com/nitrojs/create-nitro-app/blob/main/.images/preview.png?raw=true\" alt=\"Preview\" style=\"max-width:100%;height:auto;display:block;\" />\n  </div>\n</details>\n\nFollow the instructions from the CLI and you will be ready to start your development server.\n\n## Add to a Vite project\n\nYou can add Nitro to any existing Vite project to get API routes, server-side rendering, and more.\n\n::steps{level=\"3\"}\n\n### Install `nitro` and `vite`\n\n:pm-install{name=\"nitro vite\"}\n\n### Add Nitro plugin to Vite\n\nAdd the Nitro plugin to your `vite.config.ts`:\n\n```ts [vite.config.ts] {2,6}\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro()\n  ],\n});\n```\n\n### Configure Nitro\n\nCreate a `nitro.config.ts` to configure the server directory:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverDir: \"./server\",\n});\n```\n\nThe `serverDir` option tells Nitro where to look for your server routes. In this example, all routes will be inside the `server/` directory.\n\n### Create an API route\n\nCreate your first API route at `server/api/test.ts`:\n\n::code-tree{defaultValue=\"server/api/test.ts\"}\n```ts [server/api/test.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => {\n  return { message: \"Hello Nitro!\" };\n});\n```\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverDir: \"./server\",\n});\n```\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n```\n::\n\nThe file path maps directly to the route URL — `server/api/test.ts` becomes `/api/test`.\n\n::tip\nAs an alternative to filesystem routing, you can declare routes programmatically using the `routes` config option. See [Programmatic route handlers](/docs/routing#programmatic-route-handlers) for more details.\n::\n\n::tip\nYou can return strings, JSON objects, `Response` instances, or readable streams from your handlers. See [Routing](/docs/routing) for more about dynamic routes, methods, and middleware.\n::\n\n\n### Start the development server\n\n:pm-run{script=\"dev -- --open\"}\n\nYour API route is now accessible at `http://localhost:3000/api/test` :sparkles:\n\n\n\n\n\n\n"
  },
  {
    "path": "docs/1.docs/4.renderer.md",
    "content": "---\nicon: ri:layout-masonry-line\nnavigation:\n  title: Renderer\n---\n\n# Nitro Renderer\n\n> Use a renderer to handle all unmatched routes with custom HTML or a templating system.\n\nThe renderer is a special handler in Nitro that catches all routes that don't match any specific API or route handler. It's commonly used for server-side rendering (SSR), serving single-page applications (SPAs), or creating custom HTML responses.\n\n## Configuration\n\nThe renderer is configured using the `renderer` option in your Nitro config:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  renderer: {\n    template: './index.html',  // Path to HTML template file\n    handler: './renderer.ts',  // Path to custom renderer handler\n    static: false,             // Treat template as static HTML (no rendu processing)\n  }\n})\n```\n\n| Option | Type | Description |\n| --- | --- | --- |\n| `template` | `string` | Path to an HTML file used as the renderer template. |\n| `handler` | `string` | Path to a custom renderer handler module. |\n| `static` | `boolean` | When `true`, skips rendu template processing and serves the HTML as-is. Auto-detected based on template syntax when not set. |\n\nSet `renderer: false` in the config to explicitly disable the renderer entirely (including auto-detection of `index.html`).\n\n## HTML template\n\n### Auto-detected `index.html`\n\nBy default, Nitro automatically looks for an `index.html` file in your project src dir.\n\nIf found, Nitro will use it as the renderer template and serve it for all unmatched routes.\n\n::code-group\n```html [index.html]\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>My Vite + Nitro App</title>\n  </head>\n  <body>\n    <div id=\"app\"></div>\n    <script type=\"module\" src=\"/src/main.ts\"></script>\n  </body>\n</html>\n```\n```ts [routes/api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  return { hello: \"API\" };\n});\n```\n::\n\n::tip\nWhen `index.html` is detected, Nitro will automatically log in the terminal: `Using index.html as renderer template.`\n::\n\nWith this setup:\n- `/api/hello` → Handled by your API routes\n- `/about`, `/contact`, etc. → Served with `index.html`\n\n### Custom HTML file\n\nYou can specify a custom HTML template file using the `renderer.template` option in your Nitro configuration.\n\n::code-group\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  renderer: {\n    template: './app.html'\n  }\n})\n```\n\n```html [app.html]\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Custom Template</title>\n  </head>\n  <body>\n    <div id=\"root\">Loading...</div>\n    <script type=\"module\" src=\"/src/main.js\"></script>\n  </body>\n</html>\n```\n::\n\n### Static templates\n\nBy default, Nitro auto-detects whether your HTML template contains [rendu](#hypertext-preprocessor-experimental) syntax. If it does, the template is processed dynamically on each request. If it doesn't, it's served as static HTML.\n\nYou can override this behavior with the `static` option:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  renderer: {\n    template: './index.html',\n    static: true // Force static serving, skip template processing\n  }\n})\n```\n\nIn production, static templates are inlined into the server bundle and served directly for optimal performance.\n\n### Hypertext Preprocessor (experimental)\n\nNitro uses [rendu](https://github.com/h3js/rendu) Hypertext Preprocessor, which provides a simple and powerful way to create dynamic HTML templates with JavaScript expressions.\n\n#### Output expressions\n\n- `{{ expression }}` — HTML-escaped output\n- `{{{ expression }}}` or `<?= expression ?>` — raw (unescaped) output\n\n```html\n<h1>Hello {{ $URL.pathname }}</h1>\n<div>{{{ '<strong>raw html</strong>' }}}</div>\n```\n\n#### Control flow\n\nUse `<? ... ?>` for JavaScript control flow:\n\n```html\n<? if ($METHOD === 'POST') { ?>\n  <p>Form submitted!</p>\n<? } else { ?>\n  <form method=\"POST\">\n    <button type=\"submit\">Submit</button>\n  </form>\n<? } ?>\n\n<ul>\n<? for (const item of ['a', 'b', 'c']) { ?>\n  <li>{{ item }}</li>\n<? } ?>\n</ul>\n```\n\n#### Server scripts\n\nUse `<script server>` to execute JavaScript on the server:\n\n```html\n<script server>\n  const data = await fetch('https://api.example.com/data').then(r => r.json());\n</script>\n<pre>{{ JSON.stringify(data) }}</pre>\n```\n\n#### Streaming content\n\nUse the `echo()` function for streaming content. It accepts strings, functions, Promises, Response objects, or ReadableStreams:\n\n```html\n<script server>\n  echo(\"Loading...\");\n  echo(async () => fetch(\"https://api.example.com/data\"));\n</script>\n```\n\n#### Global variables\n\nAccess request context within templates:\n\n| Variable | Description |\n| --- | --- |\n| `$REQUEST` | The incoming `Request` object |\n| `$METHOD` | HTTP method (`GET`, `POST`, etc.) |\n| `$URL` | Request `URL` object |\n| `$HEADERS` | Request headers |\n| `$RESPONSE` | Response configuration object |\n| `$COOKIES` | Read-only object containing request cookies |\n\n#### Built-in functions\n\n| Function | Description |\n| --- | --- |\n| `htmlspecialchars(str)` | Escape HTML characters (automatically applied in `{{ }}` syntax) |\n| `setCookie(name, value, options?)` | Set a cookie in the response |\n| `redirect(url)` | Redirect the user to another URL |\n| `echo(content)` | Stream content to the response |\n\n```html [index.html]\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Dynamic template</title>\n  </head>\n  <body>\n    <h1>Hello {{ $REQUEST.url }}</h1>\n    <p>Welcome, <?= $COOKIES[\"user\"] || \"Guest\" ?>!</p>\n    <script server>\n      setCookie(\"visited\", \"true\", { maxAge: 3600 });\n    </script>\n  </body>\n</html>\n```\n\n:read-more{to=\"https://github.com/h3js/rendu\" title=\"Rendu Documentation\"}\n\n## Custom renderer handler\n\nFor more complex scenarios, you can create a custom renderer handler that programmatically generates responses.\n\nThe handler is a default export function that receives an H3 event object. You can access the incoming `Request` via `event.req`:\n\n```ts [renderer.ts]\nexport default function renderer({ req }: { req: Request }) {\n  const url = new URL(req.url);\n  return new Response(\n    /* html */ `<!DOCTYPE html>\n    <html>\n    <head>\n      <title>Custom Renderer</title>\n    </head>\n    <body>\n      <h1>Hello from custom renderer!</h1>\n      <p>Current path: ${url.pathname}</p>\n    </body>\n    </html>`,\n    { headers: { \"content-type\": \"text/html; charset=utf-8\" } }\n  );\n}\n```\n\nThen, specify the renderer entry in the Nitro config:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  renderer: {\n    handler: './renderer.ts'\n  }\n})\n```\n\n::note\nWhen `renderer.handler` is set, it takes full control of rendering. The `renderer.template` option is ignored.\n::\n\n## Renderer priority\n\nThe renderer always acts as a catch-all route (`/**`) and has the **lowest priority**. This means:\n\n1. Specific API routes are matched first (e.g., `/api/users`)\n2. Specific server routes are matched next (e.g., `/about`)\n3. The renderer catches everything else\n\n```md\napi/\n  users.ts        → /api/users (matched first)\nroutes/\n  about.ts        → /about (matched second)\nrenderer.ts         → /** (catches all other routes)\n```\n\n::warning\nIf you define a catch-all route (`[...].ts`) in your routes, Nitro will warn you that the renderer will override it. Use more specific routes or different HTTP methods to avoid conflicts.\n::\n\n:read-more{to=\"/docs/lifecycle\" title=\"Lifecycle\"}\n\n## Vite integration\n\nWhen using Nitro with Vite, the renderer integrates with Vite's build pipeline and dev server.\n\n### Development mode\n\nIn development, the renderer template is read from disk on each request, so changes to `index.html` are reflected immediately without restarting the server. Vite's `transformIndexHtml` hook is applied to inject HMR client scripts and other dev-time transforms.\n\n### SSR with `<!--ssr-outlet-->`\n\nWhen using Vite environments with an `ssr` service, you can add an `<!--ssr-outlet-->` comment to your `index.html`. Nitro will replace it with the output from your SSR entry during rendering:\n\n```html [index.html]\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>SSR App</title>\n  </head>\n  <body>\n    <div id=\"app\"><!--ssr-outlet--></div>\n    <script type=\"module\" src=\"/src/main.ts\"></script>\n  </body>\n</html>\n```\n\n### Production build\n\nDuring production builds, Vite processes the `index.html` through its build pipeline (resolving scripts, CSS, and other assets), then Nitro inlines the transformed HTML into the server bundle.\n\n## Use Cases\n\n### Single-Page Application (SPA)\n\nServe your SPA's `index.html` for all routes to enable client-side routing:\n\n> [!TIP]\n> This is the default behavior of Nitro when used with Vite.\n\n<!-- ### Server-Side Rendering (SSR) -->\n\n<!-- TODO: Add example with ssr-outlet and vite -->\n"
  },
  {
    "path": "docs/1.docs/5.routing.md",
    "content": "---\nicon: ri:direction-line\n---\n\n# Routing\n\n> Nitro supports filesystem routing to automatically map files to routes. By combining code-splitting with compiled routes, it removes the need for a runtime router, leaving only minimal compiled logic.\n\n## Request handler\n\nNitro request handler is a function accepting an `event` object, which is a [H3Event](https://h3.dev/guide/api/h3event#h3event-properties) object.\n\n::code-group\n```ts [Single function]\nimport type { H3Event } from \"nitro\";\n\nexport default (event: H3Event) => {\n  return \"world\";\n}\n```\n```ts [defineHandler]\nimport { defineHandler } from \"nitro\";\n\n// For better type inference\nexport default defineHandler((event) => {\n  return \"world\";\n});\n```\n::\n\n## Filesystem routing\n\nNitro supports file-based routing for your API routes (files are automatically mapped to [h3 routes](https://h3.dev/guide/basics/routing)). Defining a route is as simple as creating a file inside the `api/` or `routes/` directory.\n\nYou can only define one handler per files and you can [append the HTTP method](#specific-request-method) to the filename to define a specific request method.\n\n```\nroutes/\n  api/\n    test.ts      <-- /api/test\n  hello.get.ts   <-- /hello (GET only)\n  hello.post.ts  <-- /hello (POST only)\nvite.config.ts\n```\n\nYou can nest routes by creating subdirectories.\n\n```txt\nroutes/\n  api/\n    [org]/\n      [repo]/\n        index.ts   <-- /api/:org/:repo\n        issues.ts  <-- /api/:org/:repo/issues\n      index.ts     <-- /api/:org\npackage.json\n```\n\n#### Route Groups\n\nIn some cases, you may want to group a set of routes together in a way which doesn't affect file-based routing. For this purpose, you can put files in a folder which is wrapped in parentheses `(` and `)`.\n\nFor example:\n```txt\nroutes/\n  api/\n    (admin)/\n      users.ts   <-- /api/users\n      reports.ts <-- /api/reports\n    (public)/\n      index.ts   <-- /api\npackage.json\n```\n> [!NOTE] The route groups are not part of the route definition and are only used for organization purposes.\n\n\n### Static routes\n\nFirst, create a file in `routes/` or `routes/api/` directory. The filename will be the route path.\n\nThen, export a fetch-compatible function:\n\n```ts [routes/api/test.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => {\n  return { hello: \"API\" };\n});\n```\n\n### Dynamic routes\n\n#### Single param\n\nTo define a route with params, use the `[<param>]` syntax where `<param>` is the name of the param. The param will be available in the `event.context.params` object or using the [`getRouterParam`](https://h3.dev/utils/request#getrouterparamevent-name-opts-decode) utility.\n\n```ts [routes/hello/[name\\\\].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  const { name } = event.context.params;\n\n  return `Hello ${name}!`;\n});\n```\n\nCall the route with the param `/hello/nitro`, you will get:\n\n```txt [Response]\nHello nitro!\n```\n\n#### Multiple params\n\nYou can define multiple params in a route using `[<param1>]/[<param2>]` syntax where each param is a folder. You **cannot** define multiple params in a single filename of folder.\n\n```ts [routes/hello/[name\\\\]/[age\\\\].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  const { name, age } = event.context.params;\n\n  return `Hello ${name}! You are ${age} years old.`;\n});\n```\n\n#### Catch-all params\n\nYou can capture all the remaining parts of a URL using `[...<param>]` syntax. This will include the `/` in the param.\n\n```ts [routes/hello/[...name\\\\].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  const { name } = event.context.params;\n\n  return `Hello ${name}!`;\n});\n```\n\nCall the route with the param `/hello/nitro/is/hot`, you will get:\n\n```txt [Response]\nHello nitro/is/hot!\n```\n\n### Specific request method\n\nYou can append the HTTP method to the filename to force the route to be matched only for a specific HTTP request method, for example `hello.get.ts` will only match for `GET` requests. You can use any HTTP method you want.\n\nSupported methods: `get`, `post`, `put`, `delete`, `patch`, `head`, `options`, `connect`, `trace`.\n\n::code-group\n```js [GET]\n// routes/users/[id].get.ts\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const { id } = event.context.params;\n\n  // Do something with id\n\n  return `User profile!`;\n});\n```\n\n```js [POST]\n// routes/users.post.ts\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const body = await event.req.json();\n\n  // Do something with body like saving it to a database\n\n  return { updated: true };\n});\n```\n::\n\n### Catch-all route\n\nYou can create a special route that will match all routes that are not matched by any other route. This is useful for creating a default route.\n\nTo create a catch-all route, create a file named `[...].ts`.\n\n```ts [routes/[...\\\\].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  return `Hello ${event.url}!`;\n});\n```\n\n### Environment specific handlers\n\nYou can specify for a route that will only be included in specific builds by adding a `.dev`, `.prod` or `.prerender` suffix to the file name, for example: `routes/test.get.dev.ts` or `routes/test.get.prod.ts`.\n\nThe suffix is placed after the method suffix (if any):\n\n```txt\nroutes/\n  env/\n    index.dev.ts       <-- /env (dev only)\n    index.get.prod.ts  <-- /env (GET, prod only)\n```\n\n> [!TIP]\n> You can specify multiple environments or specify a preset name as environment using programmatic registration of routes via [`routes`](#routes-config) config.\n\n### Ignoring files\n\nYou can use the `ignore` config option to exclude files from route scanning. It accepts an array of glob patterns relative to the server directory.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  ignore: [\n    \"routes/api/**/_*\",   // Ignore files starting with _ in api/\n    \"middleware/_*.ts\",    // Ignore middleware starting with _\n    \"routes/_*.ts\",       // Ignore root routes starting with _\n  ],\n});\n```\n\n## Programmatic route handlers\n\nIn addition to filesystem routing, you can register route handlers programmatically using the `routes` config option.\n\n### `routes` config\n\nThe `routes` option allows you to map route patterns to handlers:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routes: {\n    \"/api/hello\": \"./server/routes/api/hello.ts\",\n    \"/api/custom\": {\n      handler: \"./server/routes/api/hello.ts\",\n      method: \"POST\",\n      lazy: true,\n    },\n    \"/virtual\": {\n      handler: \"#virtual-route\",\n    },\n  },\n});\n```\n\nEach route entry can be a simple string (handler path) or an object with the following options:\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `handler` | `string` | Path to event handler file or virtual module ID |\n| `method` | `string` | HTTP method to match (`get`, `post`, etc.) |\n| `lazy` | `boolean` | Use lazy loading to import handler |\n| `format` | `\"web\" \\| \"node\"` | Handler type. `\"node\"` handlers are converted to web-compatible |\n| `env` | `string \\| string[]` | Environments to include this handler (`\"dev\"`, `\"prod\"`, `\"prerender\"`, or a preset name) |\n\n### `handlers` config\n\nThe `handlers` array is useful for registering middleware with control over route matching:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  handlers: [\n    {\n      route: \"/api/**\",\n      handler: \"./server/middleware/api-auth.ts\",\n      middleware: true,\n    },\n  ],\n});\n```\n\nEach handler entry supports the following options:\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `route` | `string` | HTTP pathname pattern (e.g., `/test`, `/api/:id`, `/blog/**`) |\n| `handler` | `string` | Path to event handler file or virtual module ID |\n| `method` | `string` | HTTP method to match (`get`, `post`, etc.) |\n| `middleware` | `boolean` | Run handler as middleware before route handlers |\n| `lazy` | `boolean` | Use lazy loading to import handler |\n| `format` | `\"web\" \\| \"node\"` | Handler type. `\"node\"` handlers are converted to web-compatible |\n| `env` | `string \\| string[]` | Environments to include this handler (`\"dev\"`, `\"prod\"`, `\"prerender\"`, or a preset name) |\n\n## Middleware\n\nNitro route middleware can hook into the request lifecycle.\n\n::tip\nA middleware can modify the request before it is processed, not after.\n::\n\nMiddleware are auto-registered within the `middleware/` directory.\n\n```md\nmiddleware/\n  auth.ts\n  logger.ts\n  ...\nroutes/\n  hello.ts\n```\n\n### Simple middleware\n\nMiddleware are defined exactly like route handlers with the only exception that they should not return anything.\nReturning from middleware behaves like returning from a request - the value will be returned as a response and further code will not be ran.\n\n```ts [middleware/auth.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  // Extends or modify the event\n  event.context.user = { name: \"Nitro\" };\n});\n```\n\nMiddleware in `middleware/` directory are automatically registered for all routes. If you want to register a middleware for a specific route, see [Object Syntax Event Handler](https://h3.dev/guide/basics/handler#object-syntax).\n\n::note\nReturning anything from a middleware will close the request and should be avoided! Any returned value from middleware will be the response and further code will not be executed however **this is not recommended to do!**\n::\n\n### Route Meta\n\nYou can define route handler meta at build-time using `defineRouteMeta` macro in the event handler files.\n\n> [!IMPORTANT]\n> This feature is currently experimental.\n\n```ts [routes/api/test.ts]\nimport { defineRouteMeta } from \"nitro\";\nimport { defineHandler } from \"nitro\";\n\ndefineRouteMeta({\n  openAPI: {\n    tags: [\"test\"],\n    description: \"Test route description\",\n    parameters: [{ in: \"query\", name: \"test\", required: true }],\n  },\n});\n\nexport default defineHandler(() => \"OK\");\n```\n\n::read-more{to=\"https://swagger.io/specification/v3/\"}\nThis feature is currently usable to specify OpenAPI meta. See swagger specification for available OpenAPI options.\n::\n\n### Execution order\n\nMiddleware are executed in directory listing order.\n\n```md\nmiddleware/\n  auth.ts <-- First\n  logger.ts <-- Second\n  ... <-- Third\n```\n\nPrefix middleware with a number to control their execution order.\n\n```md\nmiddleware/\n  1.logger.ts <-- First\n  2.auth.ts <-- Second\n  3.... <-- Third\n```\n::note\nRemember that file names are sorted as strings, thus for example if you have 3 files `1.filename.ts`, `2.filename.ts` and `10.filename.ts`, the `10.filename.ts` will come after the `1.filename.ts`. To avoid this, prefix `1-9` with a `0` like `01`, if you have more than 10 middleware in the same directory.\n::\n\n### Request filtering\n\nMiddleware are executed on every request.\n\nApply custom logic to scope them to specific conditions.\n\nFor example, you can use the URL to apply a middleware to a specific route:\n\n```ts [middleware/auth.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  // Will only execute for /auth route\n  if (event.url.pathname.startsWith('/auth')) {\n    event.context.user = { name: \"Nitro\" };\n  }\n});\n```\n\n### Route-scoped middleware\n\nYou can register middleware for specific route patterns using the [`handlers`](#handlers-config) config with the `middleware` option and a specific `route`:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  handlers: [\n    {\n      route: \"/api/**\",\n      handler: \"./server/middleware/api-auth.ts\",\n      middleware: true,\n    },\n  ],\n});\n```\n\nUnlike global middleware (registered in the `middleware/` directory which match `/**`), route-scoped middleware only run for requests matching the specified pattern.\n\n## Error handling\n\nYou can use the [utilities available in H3](https://h3.dev/guide/basics/error) to handle errors in both routes and middlewares.\n\nThe way errors are sent back to the client depends on the environment. In development, requests with an `Accept` header of `text/html` (such as browsers) will receive a HTML error page. In production, errors are always sent in JSON.\n\nThis behaviour can be overridden by some request properties (e.g.: `Accept` or `User-Agent` headers).\n\n## Code splitting\n\nNitro creates a separate chunk for each route handler. Chunks load on-demand when first requested, so `/api/users` doesn't load code for `/api/posts`.\n\nSee [`inlineDynamicImports`](/config#inlinedynamicimports) to bundle everything into a single file.\n\n## Route rules\n\nNitro allows you to add logic at the top-level for each route of your configuration. It can be used for redirecting, proxying, caching, authentication, and adding headers to routes.\n\nIt is a map from route pattern (following [rou3](https://github.com/h3js/rou3)) to route options.\n\nWhen `cache` option is set, handlers matching pattern will be automatically wrapped with `defineCachedEventHandler`. See the [cache guide](/docs/cache) to learn more about this function.\n\n::note\n`swr: true|number` is shortcut for `cache: { swr: true, maxAge: number }`\n::\n\nYou can set route rules in the `nitro.routeRules` options.\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/blog/**': { swr: true },\n    '/blog2/**': { swr: 600 },\n    '/blog3/**': { static: true },\n    '/blog4/**': { cache: { /* cache options*/ } },\n    '/assets/**': { headers: { 'cache-control': 's-maxage=0' } },\n    '/api/v1/**': { cors: true, headers: { 'access-control-allow-methods': 'GET' } },\n    '/old-page': { redirect: '/new-page' },\n    '/old-page/**': { redirect: '/new-page/**' },\n    '/proxy/example': { proxy: 'https://example.com' },\n    '/proxy/**': { proxy: '/api/**' },\n    '/admin/**': { basicAuth: { username: 'admin', password: 'supersecret' } },\n  }\n});\n```\n\n### Rule merging and overrides\n\nRoute rules are matched from least specific to most specific. When multiple rules match a request, their options are merged, with more specific rules taking precedence.\n\nYou can use `false` to disable a rule that was set by a more general pattern:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/api/cached/**': { swr: true },\n    '/api/cached/no-cache': { cache: false, swr: false },\n    '/admin/**': { basicAuth: { username: 'admin', password: 'secret' } },\n    '/admin/public/**': { basicAuth: false },\n  }\n});\n```\n\n### Headers\n\nSet custom response headers for matching routes:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/api/**': { headers: { 'cache-control': 's-maxage=60' } },\n    '**': { headers: { 'x-powered-by': 'Nitro' } },\n  }\n});\n```\n\n### CORS\n\nEnable CORS headers with the `cors: true` shortcut. This sets `access-control-allow-origin: *`, `access-control-allow-methods: *`, `access-control-allow-headers: *`, and `access-control-max-age: 0`.\n\nYou can override individual CORS headers using `headers`:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/api/v1/**': {\n      cors: true,\n      headers: { 'access-control-allow-methods': 'GET' },\n    },\n  }\n});\n```\n\n### Redirect\n\nRedirect matching routes to another URL. Use a string for a simple redirect (defaults to `307` status), or an object for more control:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    // Simple redirect (307 status)\n    '/old-page': { redirect: '/new-page' },\n    // Redirect with custom status\n    '/legacy': { redirect: { to: 'https://example.com/', status: 308 } },\n    // Wildcard redirect — preserves the path after the pattern\n    '/old-blog/**': { redirect: 'https://blog.example.com/**' },\n  }\n});\n```\n\n### Proxy\n\nProxy requests to another URL. Supports both internal and external targets:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    // Proxy to exact URL\n    '/api/proxy/example': { proxy: 'https://example.com' },\n    // Proxy to internal route\n    '/api/proxy/**': { proxy: '/api/echo' },\n    // Wildcard proxy — preserves the path after the pattern\n    '/cdn/**': { proxy: 'https://cdn.jsdelivr.net/**' },\n    // Proxy with options\n    '/external/**': {\n      proxy: {\n        to: 'https://api.example.com/**',\n        // Additional H3 proxy options...\n      },\n    },\n  }\n});\n```\n\n### Basic auth\n\nProtect routes with HTTP Basic Authentication:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/admin/**': {\n      basicAuth: {\n        username: 'admin',\n        password: 'supersecret',\n        realm: 'Admin Area',  // Optional, shown in the browser prompt\n      },\n    },\n    // Disable basic auth for a sub-path\n    '/admin/public/**': { basicAuth: false },\n  }\n});\n```\n\n### Caching (SWR / Static)\n\nControl caching behavior with `cache`, `swr`, or `static` options:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    // Enable stale-while-revalidate caching\n    '/blog/**': { swr: true },\n    // SWR with maxAge in seconds\n    '/blog/posts/**': { swr: 600 },\n    // Full cache options\n    '/api/data/**': {\n      cache: {\n        maxAge: 60,\n        swr: true,\n        // ...other cache options\n      },\n    },\n    // Disable caching\n    '/api/realtime/**': { cache: false },\n  }\n});\n```\n\n::tip\n`swr: true` is a shortcut for `cache: { swr: true }` and `swr: <number>` is a shortcut for `cache: { swr: true, maxAge: <number> }`.\n::\n\n### Prerender\n\nMark routes for prerendering at build time:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/about': { prerender: true },\n    '/dynamic/**': { prerender: false },\n  }\n});\n```\n\n### ISR (Vercel)\n\nConfigure Incremental Static Regeneration for Vercel deployments:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/isr/**': { isr: true },\n    '/isr-ttl/**': { isr: 60 },\n    '/isr-custom/**': {\n      isr: {\n        expiration: 60,\n        allowQuery: ['q'],\n        group: 1,\n      },\n    },\n  }\n});\n```\n\n### Route rules reference\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `headers` | `Record<string, string>` | Custom response headers |\n| `redirect` | `string \\| { to: string, status?: number }` | Redirect to another URL (default status: `307`) |\n| `proxy` | `string \\| { to: string, ...proxyOptions }` | Proxy requests to another URL |\n| `cors` | `boolean` | Enable permissive CORS headers |\n| `cache` | `object \\| false` | Cache options (see [cache guide](/docs/cache)) |\n| `swr` | `boolean \\| number` | Shortcut for `cache: { swr: true, maxAge: number }` |\n| `static` | `boolean \\| number` | Shortcut for static caching |\n| `basicAuth` | `{ username, password, realm? } \\| false` | HTTP Basic Authentication |\n| `prerender` | `boolean` | Enable/disable prerendering |\n| `isr` | `boolean \\| number \\| object` | Incremental Static Regeneration (Vercel) |\n\n### Runtime route rules\n\nRoute rules can be provided through `runtimeConfig`, allowing overrides via environment variables without rebuilding:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  runtimeConfig: {\n    nitro: {\n      routeRules: {\n        '/api/**': { headers: { 'x-env': 'production' } },\n      },\n    },\n  },\n});\n```\n\n## Config reference\n\nThese config options control routing behavior:\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `baseURL` | `string` | `\"/\"` | Base URL for all routes |\n| `apiBaseURL` | `string` | `\"/api\"` | Base URL for routes in the `api/` directory |\n| `apiDir` | `string` | `\"api\"` | Directory name for API routes |\n| `routesDir` | `string` | `\"routes\"` | Directory name for file-based routes |\n| `serverDir` | `string \\| false` | `false` | Server directory for scanning routes, middleware, plugins, etc. |\n| `scanDirs` | `string[]` | `[]` | Additional directories to scan for routes |\n| `routes` | `Record<string, string \\| handler>` | `{}` | Route-to-handler mapping |\n| `handlers` | `NitroEventHandler[]` | `[]` | Programmatic handler registration (mainly for middleware) |\n| `routeRules` | `Record<string, NitroRouteConfig>` | `{}` | Route rules for matching patterns |\n| `ignore` | `string[]` | `[]` | Glob patterns to ignore during file scanning |\n"
  },
  {
    "path": "docs/1.docs/50.assets.md",
    "content": "---\nicon: ri:image-2-line\n---\n\n# Assets\n\nNitro supports two types of assets: **public assets** served directly to clients and **server assets** bundled into the server for programmatic access.\n\n## Public Assets\n\nNitro handles assets via the `public/` directory.\n\nAll assets in `public/` directory will be automatically served. This means that you can access them directly from the browser without any special configuration.\n\n```md\npublic/\n  image.png     <-- /image.png\n  video.mp4     <-- /video.mp4\n  robots.txt    <-- /robots.txt\n```\n\n### Caching and Headers\n\nPublic assets are served with automatic `ETag` and `Last-Modified` headers for conditional requests. When the client sends `If-None-Match` or `If-Modified-Since` headers, Nitro returns a `304 Not Modified` response.\n\nFor assets served from a non-root `baseURL` (such as `/build/`), Nitro prevents fallthrough to application handlers. If a request matches a public asset base but the file is not found, a `404` is returned immediately.\n\n### Production Public Assets\n\nWhen building your Nitro app, the `public/` directory will be copied to `.output/public/` and a manifest with metadata will be created and embedded in the server bundle.\n\n```json\n{\n  \"/image.png\": {\n    \"type\": \"image/png\",\n    \"etag\": \"\\\"4a0c-6utWq0Kbk5OqDmksYCa9XV8irnM\\\"\",\n    \"mtime\": \"2023-03-04T21:39:45.086Z\",\n    \"size\": 18956\n  },\n  \"/robots.txt\": {\n    \"type\": \"text/plain; charset=utf-8\",\n    \"etag\": \"\\\"8-hMqyDrA8fJ0R904zgEPs3L55Jls\\\"\",\n    \"mtime\": \"2023-03-04T21:39:45.086Z\",\n    \"size\": 8\n  },\n  \"/video.mp4\": {\n    \"type\": \"video/mp4\",\n    \"etag\": \"\\\"9b943-4UwfQXKUjPCesGPr6J5j7GzNYGU\\\"\",\n    \"mtime\": \"2023-03-04T21:39:45.085Z\",\n    \"size\": 637251\n  }\n}\n```\n\nThis allows Nitro to know the public assets without scanning the directory, giving high performance with caching headers.\n\n### Custom Public Asset Directories\n\nYou can configure additional public asset directories using the `publicAssets` config option. Each entry supports the following properties:\n\n- `dir` -- Path to the directory (resolved relative to `rootDir`).\n- `baseURL` -- URL prefix for serving assets (default: `\"/\"`).\n- `maxAge` -- Cache `max-age` in seconds. When set, a `Cache-Control: public, max-age=<value>, immutable` header is applied via route rules.\n- `fallthrough` -- Whether requests should fall through to application handlers when the asset is not found. Top-level (`baseURL: \"/\"`) directories default to `true`; non-root directories default to `false`.\n- `ignore` -- Pass `false` to disable ignore patterns, or an array of glob patterns to override the global `ignore` option.\n\n```js [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  publicAssets: [\n    {\n      baseURL: \"build\",\n      dir: \"public/build\",\n      maxAge: 3600,\n    },\n  ],\n});\n```\n\nIn this example, files in `public/build/` are served under `/build/` with a one-hour cache and no fallthrough to application handlers.\n\n### Compressed Public Assets\n\nNitro can generate pre-compressed versions of your public assets during the build. When a client sends an `Accept-Encoding` header, the server will serve the compressed version if available. Supported encodings are gzip (`.gz`), brotli (`.br`), and zstd (`.zst`).\n\nSet `compressPublicAssets: true` to enable all encodings:\n\n```js [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  compressPublicAssets: true,\n});\n```\n\nOr pick specific encodings:\n\n```js [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  compressPublicAssets: {\n    gzip: true,\n    brotli: true,\n    zstd: false,\n  },\n});\n```\n\n> [!NOTE]\n> Only compressible MIME types (text, JavaScript, JSON, XML, WASM, fonts, SVG, etc.) with a file size of at least 1 KB are compressed. Source map files (`.map`) are excluded.\n\n## Server Assets\n\nAll assets in `assets/` directory will be added to the server bundle. After building your application, you can find them in the `.output/server/chunks/raw/` directory. Be careful with the size of your assets, as they will be bundled with the server bundle.\n\n> [!TIP]\n> Unless using `useStorage()`, assets won't be included in the server bundle.\n\nThey can be addressed by the `assets:server` mount point using the [storage layer](/docs/storage).\n\nFor example, you could store a json file in `assets/data.json` and retrieve it in your handler:\n\n```js\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async () => {\n  const data = await useStorage(\"assets:server\").get(\"data.json\");\n\n  return data;\n});\n```\n\n### Custom Server Assets\n\nIn order to add assets from a custom directory, you will need to define a path in your nitro config. This allows you to add assets from a directory outside of the `assets/` directory.\n\nEach entry in `serverAssets` supports the following properties:\n\n- `baseName` -- Name used as the storage mount point (accessed via `assets:<baseName>`).\n- `dir` -- Path to the directory (resolved relative to `rootDir`).\n- `pattern` -- Glob pattern for file inclusion (default: `\"**/*\"`).\n- `ignore` -- Array of glob patterns to exclude files.\n\n```js [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverAssets: [\n    {\n      baseName: \"templates\",\n      dir: \"./templates\",\n    },\n  ],\n});\n```\n\nThen you can use the `assets:templates` base to retrieve your assets.\n\n```ts [handlers/success.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const html = await useStorage(\"assets:templates\").get(\"success.html\");\n\n  return html;\n});\n```\n\n> [!TIP]\n> During development, server assets are read directly from the filesystem using the `fs` unstorage driver. In production, they are bundled into the server as lazy imports with pre-computed metadata (MIME type, ETag, modification time).\n"
  },
  {
    "path": "docs/1.docs/50.configuration.md",
    "content": "---\nicon: ri:settings-3-line\n---\n\n# Configuration\n\n> Customize and extend Nitro defaults.\n\n::read-more{to=\"/config\"}\nSee [config reference](/config) for available options.\n::\n\n## Config file\n\nYou can customize your Nitro builder with a configuration file.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  // Nitro options\n})\n```\n```ts [vite.config.ts]\nimport { defineConfig } from 'vite'\nimport { nitro } from 'nitro/vite'\n\nexport default defineConfig({\n  plugins: [\n    nitro()\n  ],\n  nitro: {\n    // Nitro options\n  }\n})\n\n```\n\n> [!TIP]\n> Nitro loads the configuration using [c12](https://github.com/unjs/c12), giving more  possibilities such as using `.nitrorc` file in current working directory or in the user's home directory.\n\n### Environment-specific config\n\nUsing [c12](https://github.com/unjs/c12) conventions, you can provide environment-specific overrides using `$development` and `$production` keys:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  logLevel: 3,\n  $development: {\n    // Options applied only in development mode\n    debug: true,\n  },\n  $production: {\n    // Options applied only in production builds\n    minify: true,\n  },\n})\n```\n\nThe environment name is `\"development\"` during `nitro dev` and `\"production\"` during `nitro build`.\n\n### Extending configs\n\nYou can extend from other configs or presets using the `extends` key:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  extends: \"./base.config\",\n})\n```\n\n### Config from `package.json`\n\nYou can also provide Nitro configuration under the `nitro` key in your `package.json` file.\n\n## Directory options\n\nNitro provides several options for controlling directory structure:\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `rootDir` | `.` (current directory) | The root directory of the project. |\n| `serverDir` | `false` | Server source directory (set to `\"server\"` or `\"./\"` to enable). |\n| `buildDir` | `node_modules/.nitro` | Directory for build artifacts. |\n| `output.dir` | `.output` | Production output directory. |\n| `output.serverDir` | `.output/server` | Server output directory. |\n| `output.publicDir` | `.output/public` | Public assets output directory. |\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverDir: \"server\",\n  buildDir: \"node_modules/.nitro\",\n  output: {\n    dir: \".output\",\n  },\n})\n```\n\n> [!NOTE]\n> The `srcDir` option is deprecated. Use `serverDir` instead.\n\n## Environment variables\n\nCertain Nitro behaviors can be configured using environment variables:\n\n| Variable | Description |\n| --- | --- |\n| `NITRO_PRESET` | Override the deployment preset. |\n| `NITRO_COMPATIBILITY_DATE` | Set the compatibility date. |\n| `NITRO_APP_BASE_URL` | Override the base URL (default: `/`). |\n\n## Runtime configuration\n\nNitro provides a runtime config API to expose configuration within your application, with the ability to update it at runtime by setting environment variables. This is useful when you want to expose different configuration values for different environments (e.g. development, staging, production). For example, you can use this to expose different API endpoints for different environments or to expose different feature flags.\n\nFirst, you need to define the runtime config in your configuration file.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  runtimeConfig: {\n    apiToken: \"dev_token\", // `dev_token` is the default value\n  }\n});\n```\n\nYou can now access the runtime config using `useRuntimeConfig()`.\n\n```ts [api/example.get.ts]\nimport { defineHandler } from \"nitro\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nexport default defineHandler((event) => {\n  return useRuntimeConfig().apiToken; // Returns `dev_token`\n});\n```\n\n### Nested objects\n\nRuntime config supports nested objects. Keys at any depth are mapped to environment variables using the `NITRO_` prefix and `UPPER_SNAKE_CASE` conversion:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  runtimeConfig: {\n    database: {\n      host: \"localhost\",\n      port: 5432,\n    },\n  },\n});\n```\n\n```bash [.env]\nNITRO_DATABASE_HOST=\"db.example.com\"\nNITRO_DATABASE_PORT=\"5433\"\n```\n\n> [!NOTE]\n> Only keys defined in `runtimeConfig` in your config file will be considered. You cannot introduce new keys using environment variables alone.\n\n### Serialization\n\nRuntime config values must be serializable (strings, numbers, booleans, plain objects, and arrays). Non-serializable values (class instances, functions, etc.) will trigger a warning at build time.\n\nValues that are `undefined` or `null` in the config are replaced with empty strings (`\"\"`) as a fallback.\n\n### Local development\n\nYou can update the runtime config using environment variables. You can use a `.env` or `.env.local` file in development and use platform variables in production (see below).\n\nCreate an `.env` file in your project root:\n\n```bash [.env]\nNITRO_API_TOKEN=\"123\"\n```\n\nRe-start the development server, fetch the `/api/example` endpoint and you should see `123` as the response instead of `dev_token`.\n\n> [!NOTE]\n> The `.env` and `.env.local` files are only loaded during development (`nitro dev`). In production, use your platform's native environment variable mechanism.\n\nDo not forget that you can still universally access environment variables using `import.meta.env` or `process.env` but avoid using them in ambient global contexts to prevent unexpected behavior.\n\n### Production\n\nYou can define variables in your production environment to update the runtime config.\n\n::warning\nAll variables must be prefixed with `NITRO_` to be applied to the runtime config. They will override the runtime config variables defined within your `nitro.config.ts` file.\n::\n\n```bash [.env]\nNITRO_API_TOKEN=\"123\"\n```\n\nIn runtime config, define key using camelCase. In environment variables, define key using snake_case and uppercase.\n\n```ts\n{\n  helloWorld: \"foo\"\n}\n```\n\n```bash\nNITRO_HELLO_WORLD=\"foo\"\n```\n\n### Custom env prefix\n\nYou can configure a secondary environment variable prefix using the `nitro.envPrefix` runtime config key. This prefix is checked in addition to the default `NITRO_` prefix:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  runtimeConfig: {\n    nitro: {\n      envPrefix: \"APP_\",\n    },\n    apiToken: \"\",\n  },\n});\n```\n\nWith this configuration, both `NITRO_API_TOKEN` and `APP_API_TOKEN` will be checked as overrides.\n\n### Env expansion\n\nWhen enabled, environment variable references using `{{VAR_NAME}}` syntax in runtime config string values are expanded at runtime:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  experimental: {\n    envExpansion: true,\n  },\n  runtimeConfig: {\n    url: \"https://{{APP_DOMAIN}}/api\",\n  },\n});\n```\n\n```bash\nAPP_DOMAIN=\"example.com\"\n```\n\nAt runtime, `useRuntimeConfig().url` will resolve to `\"https://example.com/api\"`.\n"
  },
  {
    "path": "docs/1.docs/50.database.md",
    "content": "---\nicon: ri:database-2-line\ntitle: Database\n---\n\n> Nitro provides a built-in and lightweight SQL database layer.\n\nThe default database connection is **preconfigured** with [SQLite](https://db0.unjs.io/connectors/sqlite) and works out of the box for development mode and any Node.js compatible production deployments. By default, data will be stored in `.data/db.sqlite`.\n\n:read-more{to=\"https://db0.unjs.io\" title=\"DB0 Documentation\"}\n\n> [!IMPORTANT]\n> Database support is currently experimental.\n> Refer to the [db0 issues](https://github.com/unjs/db0/issues) for status and bug report.\n\nIn order to enable database layer you need to enable experimental feature flag.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  experimental: {\n    database: true\n  }\n})\n```\n\n> [!TIP]\n> You can change default connection or define more connections to any of the [supported databases](https://db0.unjs.io/connectors/sqlite).\n\n> [!TIP]\n> You can integrate database instance to any of the [supported ORMs](https://db0.unjs.io/integrations).\n\n\n## Usage\n\n<!-- automd:file code src=\"../../examples/database/server.ts\" -->\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineHandler(async () => {\n  const db = useDatabase();\n\n  // Create users table\n  await db.sql`DROP TABLE IF EXISTS users`;\n  await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n  // Add a new user\n  const userId = String(Math.round(Math.random() * 10_000));\n  await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;\n\n  // Query for users\n  const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\n\n  return {\n    rows,\n  };\n});\n```\n\n<!-- /automd -->\n\n### `useDatabase`\n\nUse `useDatabase` to get a database instance. It accepts an optional connection name (defaults to `\"default\"`).\n\n```ts\nimport { useDatabase } from \"nitro/database\";\n\n// Use the default connection\nconst db = useDatabase();\n\n// Use a named connection\nconst usersDb = useDatabase(\"users\");\n```\n\n> [!NOTE]\n> When `experimental.database` is enabled, `useDatabase` is auto-imported and available without an explicit import statement.\n\nDatabase instances are created lazily on first use and cached for subsequent calls with the same connection name. If a connection name is not configured, an error will be thrown.\n\n### `db.sql`\n\nExecute SQL queries using tagged template literals with automatic parameter binding:\n\n```ts\nconst db = useDatabase();\n\n// Insert with parameterized values (safe from SQL injection)\nconst id = \"1001\";\nawait db.sql`INSERT INTO users VALUES (${id}, 'John', 'Doe', 'john@example.com')`;\n\n// Query with parameters\nconst { rows } = await db.sql`SELECT * FROM users WHERE id = ${id}`;\n\n// The result includes rows, changes count, and last insert ID\nconst result = await db.sql`INSERT INTO posts (title) VALUES (${\"Hello\"})`;\n// result.rows, result.changes, result.lastInsertRowid\n```\n\n### `db.exec`\n\nExecute a raw SQL string directly:\n\n```ts\nconst db = useDatabase();\n\nawait db.exec(\"CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, name TEXT)\");\n```\n\n### `db.prepare`\n\nPrepare an SQL statement for repeated execution:\n\n```ts\nconst db = useDatabase();\n\nconst stmt = db.prepare(\"SELECT * FROM users WHERE id = ?\");\nconst result = await stmt.bind(\"1001\").all();\n```\n\n## Configuration\n\nYou can configure database connections using `database` config:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  database: {\n    default: {\n      connector: \"sqlite\",\n      options: { name: \"db\" }\n    },\n    users: {\n      connector: \"postgresql\",\n      options: {\n        url: \"postgresql://username:password@hostname:port/database_name\"\n      },\n    },\n  },\n});\n```\n\n### Development Database\n\nUse the `devDatabase` config to override the database configuration **only for development mode**. This is useful for using a local SQLite database during development while targeting a different database in production.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  database: {\n    default: {\n      connector: \"postgresql\",\n      options: {\n        url: \"postgresql://username:password@hostname:port/database_name\"\n      }\n    }\n  },\n  devDatabase: {\n    default: {\n      connector: \"sqlite\",\n      options: { name: \"dev-db\" }\n    }\n  }\n});\n```\n\n> [!TIP]\n> When `experimental.database` is enabled and no `database` or `devDatabase` config is provided, Nitro automatically configures a default SQLite connection. In development mode, data is stored relative to the project root directory. In Node.js production, it uses the default SQLite path.\n\n## Connectors\n\nNitro supports all [db0 connectors](https://db0.unjs.io/connectors). The `connector` field in the database config accepts any of the following values:\n\n| Connector | Description |\n|---|---|\n| `sqlite` | Node.js built-in SQLite (alias for `node-sqlite`) |\n| `node-sqlite` | Node.js built-in SQLite |\n| `better-sqlite3` | [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) |\n| `sqlite3` | [sqlite3](https://github.com/TryGhost/node-sqlite3) |\n| `bun` / `bun-sqlite` | Bun built-in SQLite |\n| `libsql` / `libsql-node` | [libSQL](https://github.com/tursodatabase/libsql) (Node.js) |\n| `libsql-http` | libSQL over HTTP |\n| `libsql-web` | libSQL for web environments |\n| `postgresql` | [PostgreSQL](https://github.com/porsager/postgres) |\n| `mysql2` | [MySQL](https://github.com/sidorares/node-mysql2) |\n| `pglite` | [PGlite](https://github.com/electric-sql/pglite) (embedded PostgreSQL) |\n| `planetscale` | [PlanetScale](https://github.com/planetscale/database-js) serverless |\n| `cloudflare-d1` | [Cloudflare D1](https://developers.cloudflare.com/d1/) |\n| `cloudflare-hyperdrive-mysql` | Cloudflare Hyperdrive with MySQL |\n| `cloudflare-hyperdrive-postgresql` | Cloudflare Hyperdrive with PostgreSQL |\n"
  },
  {
    "path": "docs/1.docs/50.lifecycle.md",
    "content": "---\nicon: i-lucide-layers\n---\n\n# Lifecycle\n\n> Understand how Nitro runs and serves incoming requests to your application.\n\n## Request lifecycle\n\nA request can be intercepted and terminated (with or without a response) from any of these layers, in this order:\n\n::steps\n\n### `request` hook\n\nThe `request` hook is the first code that runs for every incoming request. It is registered via a [server plugin](/docs/plugins):\n\n```ts [plugins/request-hook.ts]\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"request\", (event) => {\n    console.log(`Incoming request on ${event.path}`);\n  });\n});\n```\n\n::note\nErrors thrown inside the `request` hook are captured by the [`error` hook](#error-handling) and do not terminate the request pipeline.\n::\n\n### Static assets\n\nWhen static asset serving is enabled (the default for most presets), Nitro checks if the request matches a file in the `public/` directory **before** any other middleware or route handler runs.\n\nIf a match is found, the static file is served immediately with appropriate `Content-Type`, `ETag`, `Last-Modified`, and `Cache-Control` headers. The request is terminated and no further middleware or routes are executed.\n\nStatic assets also support content negotiation for pre-compressed files (gzip, brotli, zstd) via the `Accept-Encoding` header.\n\n### Route rules\n\nThe matching route rules defined in the Nitro config will execute. Route rules run as middleware so most of them alter the response without terminating it (for instance, adding a header or setting a cache policy).\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    '/**': { headers: { 'x-nitro': 'first' } }\n  }\n})\n```\n\n:read-more{to=\"/docs/routing#route-rules\" title=\"Routing > Route rules\"}\n\n### Global middleware\n\nAny global middleware defined in the `middleware/` directory will be run:\n\n```ts [middleware/info.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  event.context.info = { name: \"Nitro\" };\n});\n```\n\n::warning\nReturning from a middleware will close the request and should be avoided when possible.\n::\n\n::read-more{to=\"/docs/routing#middleware\"}\nLearn more about Nitro middleware.\n::\n\n### Routed middleware\n\nMiddleware that targets a specific route pattern (defined with a `route` in `middleware/`) runs after global middleware but before the matched route handler.\n\n### Routes\n\nNitro will look at defined routes in the `routes/` folder to match the incoming request.\n\n```ts [routes/api/hello.ts]\nexport default (event) => ({ world: true })\n```\n\n::read-more{to=\"/docs/routing#filesystem-routing\"}\nLearn more about Nitro file-system routing.\n::\n\nIf serverEntry is defined it will catch all requests not matching any other route acting as `/**` route handler.\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  if (event.path === \"/\") {\n    return \"Home page\";\n  }\n});\n```\n\n::read-more{to=\"/docs/server-entry\"}\nLearn more about Nitro server entry.\n::\n\n### Renderer\n\nIf no route is matched, Nitro will look for a renderer handler (defined or auto-detected) to handle the request.\n\n::read-more{to=\"/docs/renderer\"}\nLearn more about Nitro renderer.\n::\n\n### `response` hook\n\nAfter the response is created (from any of the layers above), the `response` hook runs. This hook receives the final `Response` object and the event, and can be used to inspect or modify response headers:\n\n```ts [plugins/response-hook.ts]\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"response\", (res, event) => {\n    console.log(`Response ${res.status} for ${event.path}`);\n  });\n});\n```\n\n::note\nThe `response` hook runs for every response, including static assets, middleware-terminated requests, and error responses.\n::\n\n::\n\n## Error handling\n\nWhen an error occurs at any point in the request lifecycle, Nitro:\n\n1. Calls the `error` hook with the error and context (including the event and source tags).\n2. Passes the error to the **error handler** which converts it into an HTTP response.\n\n```ts [plugins/errors.ts]\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"error\", (error, context) => {\n    console.error(\"Captured error:\", error);\n    // context.event - the H3 event (if available)\n    // context.tags  - error source tags like \"request\", \"response\", \"plugin\"\n  });\n});\n```\n\nErrors are also tracked per-request in `event.req.context.nitro.errors` for inspection in later hooks.\n\nYou can provide a custom error handler in the Nitro config to control error response formatting:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  errorHandler: \"~/error\",\n})\n```\n\nAdditionally, unhandled promise rejections and uncaught exceptions at the process level are automatically captured into the `error` hook with the tags `\"unhandledRejection\"` and `\"uncaughtException\"`.\n\n## Server shutdown\n\nWhen the Nitro server is shutting down, the `close` hook is called. Use this to clean up resources such as database connections, timers, or external service handles:\n\n```ts [plugins/cleanup.ts]\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"close\", async () => {\n    // Clean up resources\n  });\n});\n```\n\n## Hooks reference\n\nAll runtime hooks are registered through [server plugins](/docs/plugins) using `nitroApp.hooks.hook()`.\n\n| Hook | Signature | When it runs |\n| --- | --- | --- |\n| `request` | `(event: HTTPEvent) => void \\| Promise<void>` | Start of each request, before routing. |\n| `response` | `(res: Response, event: HTTPEvent) => void \\| Promise<void>` | After the response is created, before it is sent. |\n| `error` | `(error: Error, context: { event?, tags? }) => void` | When any error is captured during the lifecycle. |\n| `close` | `() => void` | When the Nitro server is shutting down. |\n\n::note\nThe `NitroRuntimeHooks` interface is augmentable. Deployment presets (such as Cloudflare) can extend it with platform-specific hooks.\n::\n\n::read-more{to=\"/docs/plugins\"}\nLearn more about Nitro plugins and hook usage examples.\n::\n"
  },
  {
    "path": "docs/1.docs/50.plugins.md",
    "content": "---\nicon: ri:plug-line\n---\n\n# Plugins\n\n> Use plugins to extend Nitro's runtime behavior.\n\nNitro plugins are **executed once** during server startup in order to allow extending Nitro's runtime behavior.\nThey receive `nitroApp` context, which can be used to hook into lifecycle events.\n\nPlugins are auto-registered from the `plugins/` directory and run synchronously by file name order on the first Nitro initialization. Plugin functions themselves must be synchronous (return `void`), but the hooks they register can be async.\n\n**Example:**\n\n```ts [plugins/test.ts]\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  console.log('Nitro plugin', nitroApp)\n})\n```\n\nIf you have plugins in another directory, you can use the `plugins` option:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  plugins: ['my-plugins/hello.ts']\n})\n```\n\n## The `nitroApp` context\n\nThe plugin function receives a `nitroApp` object with the following properties:\n\n| Property | Type | Description |\n| --- | --- | --- |\n| `hooks` | [`HookableCore`](https://github.com/unjs/hookable) | Hook system for registering lifecycle callbacks. |\n| `h3` | `H3Core` | The underlying [H3](https://github.com/h3js/h3) application instance. |\n| `fetch` | `(req: Request) => Response \\| Promise<Response>` | The app's internal fetch handler. |\n| `captureError` | `(error: Error, context) => void` | Programmatically capture errors into the error hook pipeline. |\n\n## Nitro runtime hooks\n\nYou can use Nitro [hooks](https://github.com/unjs/hookable) to extend the default runtime behaviour of Nitro by registering custom functions to the lifecycle events within plugins.\n\n**Example:**\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"close\", async () => {\n    // Will run when nitro is being closed\n  });\n})\n```\n\n### Available hooks\n\n| Hook | Signature | Description |\n| --- | --- | --- |\n| `request` | `(event: HTTPEvent) => void \\| Promise<void>` | Called at the start of each request. |\n| `response` | `(res: Response, event: HTTPEvent) => void \\| Promise<void>` | Called after the response is created. |\n| `error` | `(error: Error, context: { event?: HTTPEvent, tags?: string[] }) => void` | Called when an error is captured. |\n| `close` | `() => void` | Called when the Nitro server is shutting down. |\n\n> [!NOTE]\n> The `NitroRuntimeHooks` interface is augmentable. Deployment presets (such as Cloudflare) can extend it with platform-specific hooks like `cloudflare:scheduled` and `cloudflare:email`.\n\n### Unregistering hooks\n\nThe `hook()` method returns an unregister function that can be called to remove the hook:\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  const unregister = nitroApp.hooks.hook(\"request\", (event) => {\n    // ...\n  });\n\n  // Later, remove the hook\n  unregister();\n});\n```\n\n## Examples\n\n### Capturing errors\n\nYou can use plugins to capture all application errors.\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"error\", async (error, { event }) => {\n    console.error(`${event?.path} Application error:`, error)\n  });\n})\n```\n\nThe `context` object includes an optional `tags` array that identifies the error source (e.g., `\"request\"`, `\"response\"`, `\"cache\"`, `\"plugin\"`, `\"unhandledRejection\"`, `\"uncaughtException\"`).\n\n### Programmatic error capture\n\nYou can use `captureError` to manually feed errors into the error hook pipeline:\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.captureError(new Error(\"something went wrong\"), {\n    tags: [\"startup\"],\n  });\n});\n```\n\n### Graceful shutdown\n\nServer will gracefully shutdown and wait for any background pending tasks initiated by `event.waitUntil`.\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"close\", async () => {\n    // Clean up resources, close connections, etc.\n  });\n});\n```\n\n### Request and response lifecycle\n\nYou can use plugins to register hooks that run on the request lifecycle:\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"request\", (event) => {\n    console.log(\"on request\", event.path);\n  });\n\n  nitroApp.hooks.hook(\"response\", (res, event) => {\n    // Modify or inspect the response\n    console.log(\"on response\", res.status);\n  });\n});\n```\n\n### Modifying response headers\n\n```ts\nimport { definePlugin } from \"nitro\";\n\nexport default definePlugin((nitroApp) => {\n  nitroApp.hooks.hook(\"response\", (res, event) => {\n    const { pathname } = new URL(event.req.url);\n    if (pathname.endsWith(\".css\") || pathname.endsWith(\".js\")) {\n      res.headers.append(\"Vary\", \"Origin\");\n    }\n  });\n});\n```\n"
  },
  {
    "path": "docs/1.docs/50.tasks.md",
    "content": "---\nicon: codicon:run-all\n---\n\n# Tasks\n\n> Nitro tasks allow on-off operations in runtime.\n\n## Opt-in to the experimental feature\n\n> [!IMPORTANT]\n> Tasks support is currently experimental.\n> See [nitrojs/nitro#1974](https://github.com/nitrojs/nitro/issues/1974) for the relevant discussion.\n\nIn order to use the tasks API you need to enable experimental feature flag.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  experimental: {\n    tasks: true\n  }\n})\n```\n\n## Define tasks\n\nTasks can be defined in `tasks/[name].ts` files.\n\nNested directories are supported. The task name will be joined with `:`. (Example: `tasks/db/migrate.ts` task name will be `db:migrate`)\n\n**Example:**\n\n```ts [tasks/db/migrate.ts]\nexport default defineTask({\n  meta: {\n    name: \"db:migrate\",\n    description: \"Run database migrations\",\n  },\n  run({ payload, context }) {\n    console.log(\"Running DB migration task...\");\n    return { result: \"Success\" };\n  },\n});\n```\n\n### Task interface\n\nThe `defineTask` helper accepts an object with the following properties:\n\n- **`meta`** (optional): An object with optional `name` and `description` string fields used for display in the dev server and CLI.\n- **`run`** (required): A function that receives a [`TaskEvent`](#taskevent) and returns (or resolves to) an object with an optional `result` property.\n\n```ts\ninterface Task<RT = unknown> {\n  meta?: { name?: string; description?: string };\n  run(event: TaskEvent): { result?: RT } | Promise<{ result?: RT }>;\n}\n```\n\n### `TaskEvent`\n\nThe `run` function receives a `TaskEvent` object with the following properties:\n\n- **`name`**: The name of the task being executed.\n- **`payload`**: An object (`Record<string, unknown>`) containing any data passed to the task.\n- **`context`**: A `TaskContext` object (may include `waitUntil` depending on the runtime).\n\n```ts\ninterface TaskEvent {\n  name: string;\n  payload: TaskPayload;\n  context: TaskContext;\n}\n```\n\n### Registering tasks via config\n\nIn addition to file-based scanning, tasks can be registered directly in the Nitro config. This is useful for tasks provided by modules or pointing to custom handler paths.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  experimental: {\n    tasks: true\n  },\n  tasks: {\n    \"db:migrate\": {\n      handler: \"./tasks/custom-migrate.ts\",\n      description: \"Run database migrations\"\n    }\n  }\n})\n```\n\nIf a task is both scanned from the `tasks/` directory and defined in the config, the config-defined `handler` takes precedence.\n\n## Scheduled tasks\n\nYou can define scheduled tasks using Nitro configuration to automatically run after each period of time.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  scheduledTasks: {\n    // Run `cms:update` task every minute\n    '* * * * *': ['cms:update'],\n    // Run a single task (string shorthand)\n    '0 * * * *': 'db:cleanup'\n  }\n})\n```\n\nThe `scheduledTasks` config maps cron expressions to either a single task name (string) or an array of task names. When multiple tasks are assigned to the same cron expression, they run in parallel.\n\n> [!TIP]\n> You can use [crontab.guru](https://crontab.guru/) to easily generate and understand cron tab patterns.\n\nWhen a scheduled task runs, it automatically receives a `payload` with `scheduledTime` set to the current timestamp (`Date.now()`).\n\n### Platform support\n\n- **`dev`**, **`node_server`**, **`node_cluster`**, **`node_middleware`**, **`bun`** and **`deno_server`** presets are supported with the [croner](https://croner.56k.guru/) engine.\n- **`cloudflare_module`** and **`cloudflare_pages`** presets have native integration with [Cron Triggers](https://developers.cloudflare.com/workers/configuration/cron-triggers/). Nitro automatically generates the cron triggers in the wrangler config at build time - no manual wrangler setup required.\n- **`vercel`** preset has native integration with [Vercel Cron Jobs](https://vercel.com/docs/cron-jobs). Nitro automatically generates the cron job configuration at build time - no manual `vercel.json` setup required. You can secure cron endpoints by setting the `CRON_SECRET` environment variable.\n- More presets (with native primitives support) are planned to be supported!\n\n## `waitUntil`\n\nWhen running background tasks, you might want to make sure the server or worker waits until the task is done.\n\nAn optional `context.waitUntil` function _might_ be available depending on the runtime.\n\n```ts\nexport default defineTask({\n  run({ context }) {\n    const promise = fetch(...)\n    context.waitUntil?.(promise);\n    await promise;\n    return { result: \"Success\" };\n  },\n});\n```\n\n## Programmatically run tasks\n\nTo manually run tasks, you can use `runTask(name, { payload?, context? })` utility from `nitro/task`.\n\n**Example:**\n\n```ts [api/migrate.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  // IMPORTANT: Authenticate user and validate payload!\n  const payload = Object.fromEntries(event.url.searchParams);\n  const { result } = await runTask(\"db:migrate\", { payload });\n\n  return { result };\n});\n```\n\n### Error handling\n\n`runTask` throws an HTTP error if:\n\n- The task does not exist (status `404`).\n- The task has no handler implementation (status `501`).\n\nAny errors thrown inside the task's `run` function will propagate to the caller.\n\n## Run tasks with dev server\n\nNitro's built-in dev server exposes tasks to be easily executed without programmatic usage.\n\n### Using API routes\n\n#### `/_nitro/tasks`\n\nThis endpoint returns a list of available task names and their meta.\n\n```json\n// [GET] /_nitro/tasks\n{\n  \"tasks\": {\n    \"db:migrate\": {\n      \"description\": \"Run database migrations\"\n    },\n     \"cms:update\": {\n      \"description\": \"Update CMS content\"\n    }\n  },\n  \"scheduledTasks\": [\n    {\n      \"cron\": \"* * * * *\",\n      \"tasks\": [\n        \"cms:update\"\n      ]\n    }\n  ]\n}\n```\n\n#### `/_nitro/tasks/:name`\n\nThis endpoint executes a task. You can provide a payload using both query parameters and body JSON payload. The payload sent in the JSON body payload must be under the `\"payload\"` property.\n\n::code-group\n```ts [tasks/echo/payload.ts]\nexport default defineTask({\n  meta: {\n    name: \"echo:payload\",\n    description: \"Returns the provided payload\",\n  },\n  run({ payload, context }) {\n    console.log(\"Running echo task...\");\n    return { result: payload };\n  },\n});\n```\n```json [GET]\n// [GET] /_nitro/tasks/echo:payload?field=value&array=1&array=2\n{\n  \"field\": \"value\",\n  \"array\": [\"1\", \"2\"]\n}\n```\n```json [POST]\n/**\n * [POST] /_nitro/tasks/echo:payload?field=value\n * body: {\n *   \"payload\": {\n *     \"answer\": 42,\n *     \"nested\": {\n *       \"value\": true\n *     }\n *   }\n * }\n */\n{\n  \"field\": \"value\",\n  \"answer\": 42,\n  \"nested\": {\n    \"value\": true\n  }\n}\n```\n::\n\n> [!NOTE]\n> The JSON payload included in the body will overwrite the keys present in the query params.\n\n### Using CLI\n\n> [!IMPORTANT]\n> It is only possible to run these commands while the **dev server is running**. You should run them in a second terminal.\n\n#### List tasks\n\n```sh\nnitro task list\n```\n\n#### Run a task\n\n```sh\nnitro task run db:migrate --payload \"{}\"\n```\n\nThe `--payload` flag accepts a JSON string that will be parsed and passed to the task. If the value is not a valid JSON object, the task runs without a payload.\n\n## Notes\n\n### Concurrency\n\nEach task can have **one running instance**. Calling a task of same name multiple times in parallel, results in calling it once and all callers will get the same return value.\n\n> [!NOTE]\n> Nitro tasks can be running multiple times and in parallel.\n"
  },
  {
    "path": "docs/1.docs/6.server-entry.md",
    "content": "---\nicon: ri:server-line\nnavigation:\n  title: Server Entry\n---\n\n# Nitro Server Entry\n\n> Use a server entry to create a global middleware that runs for all routes before they are matched.\n\nThe server entry is a special handler in Nitro that acts as a global middleware, running for every incoming request before routes are matched. It's commonly used for cross-cutting concerns like authentication, logging, request preprocessing, or creating custom routing logic.\n\n## Auto-detected `server.ts`\n\nBy default, Nitro automatically looks for a `server.ts` (or `.js`, `.mjs`, `.mts`, `.tsx`, `.jsx`) file in your project root directory.\n\nIf found, Nitro will use it as the server entry and run it for all incoming requests.\n\n::code-group\n```ts [server.ts]\nexport default {\n  async fetch(req: Request) {\n    const url = new URL(req.url);\n\n    // Handle specific routes\n    if (url.pathname === \"/health\") {\n      return new Response(\"OK\", {\n        status: 200,\n        headers: { \"content-type\": \"text/plain\" }\n      });\n    }\n\n    // Add custom headers to all requests\n    // Return nothing to continue to the next handler\n  }\n}\n```\n```ts [routes/api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  return { hello: \"API\" };\n});\n```\n::\n\n::tip\nWhen `server.ts` is detected, Nitro will log in the terminal: `Detected \\`server.ts\\` as server entry.`\n::\n\nWith this setup:\n- `/health` → Handled by server entry (returns a response)\n- `/api/hello` → Handled by the API route handler directly\n- `/about`, etc. → Server entry runs first, then continues to the renderer if no response is returned\n\n## Framework compatibility\n\nThe server entry is a great way to integrate with other frameworks. Any framework that exposes a standard Web `fetch(request: Request): Response` interface can be used as a server entry.\n\n### Web-compatible frameworks\n\nFrameworks that implement the Web `fetch` API work directly with `server.ts`:\n\n::tabs\n  ::tabs-item{label=\"H3\" icon=\"i-undocs-h3\"}\n  ```ts [server.ts]\n  import { H3 } from \"h3\";\n\n  const app = new H3()\n\n  app.get(\"/\", () => \"⚡️ Hello from H3!\");\n\n  export default app;\n  ```\n  ::\n  ::tabs-item{label=\"Hono\" icon=\"i-undocs-hono\"}\n  ```ts [server.ts]\n  import { Hono } from \"hono\";\n\n  const app = new Hono();\n\n  app.get(\"/\", (c) => c.text(\"🔥 Hello from Hono!\"));\n\n  export default app;\n  ```\n  ::\n  ::tabs-item{label=\"Elysia\" icon=\"i-undocs-elysia\"}\n  ```ts [server.ts]\n  import { Elysia } from \"elysia\";\n\n  const app = new Elysia();\n\n  app.get(\"/\", () => \"🦊 Hello from Elysia!\");\n\n  export default app.compile();\n  ```\n  ::\n::\n\n### Node.js frameworks\n\nFor Node.js frameworks that use `(req, res)` style handlers (like [Express](https://expressjs.com/) or [Fastify](https://fastify.dev/)), name your server entry file `server.node.ts` instead of `server.ts`. Nitro will automatically detect the `.node.` suffix and convert the Node.js handler to a web-compatible fetch handler using [`srvx`](https://srvx.h3.dev/).\n\n::tabs\n  ::tabs-item{label=\"Express\"}\n  ```ts [server.node.ts]\n  import Express from \"express\";\n\n  const app = Express();\n\n  app.use(\"/\", (_req, res) => {\n    res.send(\"Hello from Express with Nitro!\");\n  });\n\n  export default app;\n  ```\n  ::\n  ::tabs-item{label=\"Fastify\"}\n  ```ts [server.node.ts]\n  import Fastify from \"fastify\";\n\n  const app = Fastify();\n\n  app.get(\"/\", () => \"Hello, Fastify with Nitro!\");\n\n  await app.ready();\n\n  export default app.routing;\n  ```\n  ::\n::\n\n\n## Configuration\n\n### Custom server entry file\n\nYou can specify a custom server entry file using the `serverEntry` option in your Nitro configuration:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverEntry: \"./nitro.server.ts\"\n})\n```\n\nYou can also provide an object with `handler` and `format` options:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverEntry: {\n    handler: \"./server.ts\",\n    format: \"node\" // \"web\" (default) or \"node\"\n  }\n})\n```\n\n### Handler format\n\nThe `format` option controls how Nitro treats the default export of your server entry:\n\n- **`\"web\"`** (default) — Expects a Web-compatible handler with a `fetch(request: Request): Response` method.\n- **`\"node\"`** — Expects a Node.js-style `(req, res)` handler. Nitro automatically converts it to a web-compatible handler.\n\nWhen auto-detecting, the format is determined by the filename: `server.node.ts` uses `\"node\"` format, while `server.ts` uses `\"web\"` format.\n\n### Disabling server entry\n\nSet `serverEntry` to `false` to disable auto-detection and prevent Nitro from using any server entry:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverEntry: false\n})\n```\n\n## Using event handler\n\nYou can also export an event handler using `defineHandler` for better type inference and access to the h3 event object:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  // Add custom context\n  event.context.requestId = crypto.randomUUID();\n  event.context.timestamp = Date.now();\n\n  // Log the request\n  console.log(`[${event.context.requestId}] ${event.method} ${event.path}`);\n\n  // Continue to the next handler (don't return anything)\n});\n```\n\n::important\nIf your server entry returns `undefined` or doesn't return anything, the request will continue to be processed by routes and the renderer. If it returns a response, the request lifecycle stops there.\n::\n\n## Request lifecycle\n\nThe server entry is registered as a catch-all (`/**`) route handler. When a specific route (like `/api/hello`) matches a request, that route handler takes priority. For requests that don't match any specific route, the server entry runs before the renderer:\n\n```md\n1. Server hook: `request`\n2. Route rules (headers, redirects, etc.)\n3. Global middleware (middleware/)\n4. Route matching:\n   a. Specific routes (routes/) ← if matched, handles the request\n   b. Server entry ← runs for unmatched routes\n   c. Renderer (renderer.ts or index.html)\n```\n\nWhen both a server entry and a renderer exist, they are chained: the server entry runs first, and if it doesn't return a response, the renderer handles the request.\n\n## Development mode\n\nDuring development, Nitro watches for changes to your server entry file. When the file is created, modified, or deleted, the dev server automatically reloads to pick up the changes.\n\n## Best practices\n\n- Use server entry for cross-cutting concerns that affect **all routes**\n- Return `undefined` to continue processing, return a response to terminate\n- Keep server entry logic lightweight for better performance\n- Use global middleware for modular concerns instead of one large server entry\n- Consider using [Nitro plugins](/docs/plugins) for initialization logic\n- Avoid heavy computation in server entry (it runs for every request)\n- Don't use server entry for route-specific logic (use route handlers instead as they are more performant)\n\n"
  },
  {
    "path": "docs/1.docs/7.cache.md",
    "content": "---\nicon: ri:speed-line\n---\n\n# Cache\n\n> Nitro provides a caching system built on top of the storage layer, powered by [ocache](https://github.com/unjs/ocache).\n\n## Cached handlers\n\nTo cache an event handler, you simply need to use the `defineCachedHandler` method.\n\nIt works like `defineHandler` but with an second parameter for the [cache options](#options).\n\n```ts [routes/cached.ts]\nimport { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler((event) => {\n  return \"I am cached for an hour\";\n}, { maxAge: 60 * 60 });\n```\n\nWith this example, the response will be cached for 1 hour and a stale value will be sent to the client while the cache is being updated in the background. If you want to immediately return the updated response set `swr: false`.\n\nSee the [options](#options) section for more details about the available options.\n\n\n::important\n**Request headers are dropped** when handling cached responses. Use the [`varies` option](#options) to consider specific headers when caching and serving the responses.\n::\n\n### Automatic HTTP headers\n\nWhen using `defineCachedHandler`, Nitro automatically manages HTTP cache headers on cached responses:\n\n- **`etag`** -- A weak ETag (`W/\"...\"`) is generated from the response body hash if not already set by the handler.\n- **`last-modified`** -- Set to the current time when the response is first cached, if not already set.\n- **`cache-control`** -- Automatically set based on the `swr`, `maxAge`, and `staleMaxAge` options:\n  - With `swr: true`: `s-maxage=<maxAge>, stale-while-revalidate=<staleMaxAge>`\n  - With `swr: false`: `max-age=<maxAge>`\n\n### Conditional requests (304 Not Modified)\n\nCached handlers automatically support conditional requests. When a client sends `if-none-match` or `if-modified-since` headers matching the cached response, Nitro returns a `304 Not Modified` response without a body.\n\n### Request method filtering\n\nOnly `GET` and `HEAD` requests are cached. All other HTTP methods (`POST`, `PUT`, `DELETE`, etc.) automatically bypass the cache and call the handler directly.\n\n### Request deduplication\n\nWhen multiple concurrent requests hit the same cache key while the cache is being resolved, only one invocation of the handler runs. All concurrent requests wait for and share the same result.\n\n## Cached functions\n\nYou can also cache a function using the `defineCachedFunction` function. This is useful for caching the result of a function that is not an event handler, but is part of one, and reusing it in multiple handlers.\n\nFor example, you might want to cache the result of an API call for one hour:\n\n```ts [routes/api/stars/[...repo\\\\].ts]\nimport { defineCachedFunction } from \"nitro/cache\";\nimport { defineHandler, type H3Event } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const { repo } = event.context.params;\n  const stars = await cachedGHStars(repo).catch(() => 0)\n\n  return { repo, stars }\n});\n\nconst cachedGHStars = defineCachedFunction(async (repo: string) => {\n  const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json());\n\n  return data.stargazers_count;\n}, {\n  maxAge: 60 * 60,\n  name: \"ghStars\",\n  getKey: (repo: string) => repo\n});\n```\n\nThe stars will be cached in development inside `.nitro/cache/functions/ghStars/<owner>/<repo>.json` with `value` being the number of stars.\n\n```json\n{\"expires\":1677851092249,\"value\":43991,\"mtime\":1677847492540,\"integrity\":\"ZUHcsxCWEH\"}\n```\n\n::important\nBecause the cached data is serialized to JSON, it is important that the cached function does not return anything that cannot be serialized, such as Symbols, Maps, Sets...\n::\n\n::callout\n  If you are using edge workers to host your application, you should follow the instructions below.\n  ::collapsible{name=\"Edge workers instructions\"}\n  In edge workers, the instance is destroyed after each request. Nitro automatically uses `event.waitUntil` to keep the instance alive while the cache is being updated while the response is sent to the client.\n\n  To ensure that your cached functions work as expected in edge workers, **you should always pass the `event` as the first argument to the function using `defineCachedFunction`.**\n\n  ```ts [routes/api/stars/[...repo\\\\].ts] {5,10,17}\n  import { defineCachedFunction } from \"nitro/cache\";\n\n\n  export default defineHandler(async (event) => {\n    const { repo } = event.context.params;\n    const stars = await cachedGHStars(event, repo).catch(() => 0)\n\n    return { repo, stars }\n  });\n\n  const cachedGHStars = defineCachedFunction(async (event: H3Event, repo: string) => {\n    const data = await fetch(`https://api.github.com/repos/${repo}`).then(res => res.json());\n\n    return data.stargazers_count;\n  }, {\n    maxAge: 60 * 60,\n    name: \"ghStars\",\n    getKey: (event: H3Event, repo: string) => repo\n  });\n  ```\n\n  This way, the function will be able to keep the instance alive while the cache is being updated without slowing down the response to the client.\n  ::\n::\n\n## Using route rules\n\nThis feature enables you to add caching routes based on a glob pattern directly in the main configuration file. This is especially useful to have a global cache strategy for a part of your application.\n\nCache all the blog routes for 1 hour with `stale-while-revalidate` behavior:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    \"/blog/**\": { cache: { maxAge: 60 * 60 } },\n  },\n});\n```\n\nIf we want to use a [custom cache storage](#cache-storage) mount point, we can use the `base` option.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    redis: {\n      driver: \"redis\",\n      url: \"redis://localhost:6379\",\n    },\n  },\n  routeRules: {\n    \"/blog/**\": { cache: { maxAge: 60 * 60, base: \"redis\" } },\n  },\n});\n```\n\n### Route rules shortcuts\n\nYou can use the `swr` shortcut for enabling `stale-while-revalidate` caching on route rules. When set to `true`, SWR is enabled with the default `maxAge`. When set to a number, it is used as the `maxAge` value in seconds.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    \"/blog/**\": { swr: true },\n    \"/api/**\": { swr: 3600 },\n  },\n});\n```\n\nTo explicitly disable caching on a route, set `cache: false`:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  routeRules: {\n    \"/api/realtime/**\": { cache: false },\n  },\n});\n```\n\n::note\nWhen using route rules, cached handlers use the group `'nitro/route-rules'` instead of the default `'nitro/handlers'`.\n::\n\n## Cache storage\n\nNitro stores the data in the `cache` storage mount point.\n\n- In production, it will use the [memory driver](https://unstorage.unjs.io/drivers/memory) by default.\n- In development, it will use the [filesystem driver](https://unstorage.unjs.io/drivers/fs), writing to a temporary dir (`.nitro/cache`).\n\nTo overwrite the production storage, set the `cache` mount point using the `storage` option:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    cache: {\n      driver: 'redis',\n      /* redis connector options */\n    }\n  }\n})\n```\n\nIn development, you can also overwrite the cache mount point using the `devStorage` option:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    cache: {\n      // production cache storage\n    },\n  },\n  devStorage: {\n    cache: {\n      // development cache storage\n    }\n  }\n})\n```\n\n## Options\n\nThe `defineCachedHandler` and `defineCachedFunction` functions accept the following options:\n\n### Shared options\n\nThese options are available for both `defineCachedHandler` and `defineCachedFunction`:\n\n::field-group\n  ::field{name=\"base\" type=\"string\"}\n    Name of the storage mountpoint to use for caching. :br\n    Default to `cache`.\n  ::\n  ::field{name=\"name\" type=\"string\"}\n    Guessed from function name if not provided, and falls back to `'_'` otherwise.\n  ::\n  ::field{name=\"group\" type=\"string\"}\n    Defaults to `'nitro/handlers'` for handlers and `'nitro/functions'` for functions.\n  ::\n  ::field{name=\"getKey()\" type=\"(...args) => string\"}\n    A function that accepts the same arguments as the original function and returns a cache key (`String`). :br\n    If not provided, a built-in hash function will be used to generate a key based on the function arguments. For cached handlers, the key is derived from the request URL path and search params.\n  ::\n  ::field{name=\"integrity\" type=\"string\"}\n    A value that invalidates the cache when changed. :br\n    By default, it is computed from **function code**, used in development to invalidate the cache when the function code changes.\n  ::\n  ::field{name=\"maxAge\" type=\"number\"}\n    Maximum age that cache is valid, in seconds. :br\n    Default to `1` (second).\n  ::\n  ::field{name=\"staleMaxAge\" type=\"number\"}\n    Maximum age that a stale cache is valid, in seconds. If set to `-1` a stale value will still be sent to the client while the cache updates in the background. :br\n    Defaults to `0` (disabled).\n  ::\n  ::field{name=\"swr\" type=\"boolean\"}\n    Enable `stale-while-revalidate` behavior to serve a stale cached response while asynchronously revalidating it. :br\n    When enabled, stale cached values are returned immediately while revalidation happens in the background. When disabled, the caller waits for the fresh value before responding (the stale entry is cleared). :br\n    Defaults to `true`.\n  ::\n  ::field{name=\"shouldInvalidateCache()\" type=\"(...args) => boolean | Promise<boolean>\"}\n    A function that returns a `boolean` to invalidate the current cache and create a new one.\n  ::\n  ::field{name=\"shouldBypassCache()\" type=\"(...args) => boolean | Promise<boolean>\"}\n    A function that returns a `boolean` to bypass the current cache without invalidating the existing entry.\n  ::\n  ::field{name=\"onError()\" type=\"(error: unknown) => void\"}\n    A custom error handler called when the cached function throws. :br\n    By default, errors are logged to the console and captured by the Nitro error handler.\n  ::\n::\n\n### Handler-only options\n\nThese options are only available for `defineCachedHandler`:\n\n::field-group\n  ::field{name=\"headersOnly\" type=\"boolean\"}\n    When `true`, skip full response caching and only handle conditional request headers (`if-none-match`, `if-modified-since`) for `304 Not Modified` responses. The handler is called on every request but benefits from conditional caching.\n  ::\n  ::field{name=\"varies\" type=\"string[]\"}\n    An array of request header names to vary the cache key on. Headers listed here are preserved on the request during cache resolution and included in the cache key, making the cache unique per combination of header values. :br :br\n    Headers **not** listed in `varies` are stripped from the request before calling the handler to ensure consistent cache hits. :br :br\n    For multi-tenant environments, you may want to pass `['host', 'x-forwarded-host']` to ensure these headers are not discarded and that the cache is unique per tenant.\n  ::\n::\n\n### Function-only options\n\nThese options are only available for `defineCachedFunction`:\n\n::field-group\n  ::field{name=\"transform()\" type=\"(entry: CacheEntry, ...args) => any\"}\n    Transform the cache entry before returning. The return value replaces the cached value.\n  ::\n  ::field{name=\"validate()\" type=\"(entry: CacheEntry, ...args) => boolean\"}\n    Validate a cache entry. Return `false` to treat the entry as invalid and trigger re-resolution.\n  ::\n::\n\n## SWR behavior\n\nThe `stale-while-revalidate` (SWR) pattern is enabled by default (`swr: true`). Understanding how it interacts with other options:\n\n| `swr` | `maxAge` | Behavior |\n|-------|----------|----------|\n| `true` (default) | `1` (default) | Cache for 1 second, serve stale while revalidating |\n| `true` | `3600` | Cache for 1 hour, serve stale while revalidating |\n| `false` | `3600` | Cache for 1 hour, wait for fresh value when expired |\n| `true` | `3600` with `staleMaxAge: 600` | Cache for 1 hour, serve stale for up to 10 minutes while revalidating |\n\nWhen `swr` is enabled and a cached value exists but has expired:\n1. The stale cached value is returned immediately to the client.\n2. The function/handler is called in the background to refresh the cache.\n3. On edge workers, `event.waitUntil` is used to keep the background refresh alive.\n\nWhen `swr` is disabled and a cached value has expired:\n1. The stale entry is cleared.\n2. The client waits for the function/handler to resolve with a fresh value.\n\n## Cache keys and invalidation\n\nWhen using the `defineCachedFunction` or `defineCachedHandler` functions, the cache key is generated using the following pattern:\n\n```ts\n`${options.base}:${options.group}:${options.name}:${options.getKey(...args)}.json`\n```\n\nFor example, the following function:\n\n```ts\nimport { defineCachedFunction } from \"nitro/cache\";\n\nconst getAccessToken = defineCachedFunction(() => {\n  return String(Date.now())\n}, {\n  maxAge: 10,\n  name: \"getAccessToken\",\n  getKey: () => \"default\"\n});\n```\n\nWill generate the following cache key:\n\n```ts\ncache:nitro/functions:getAccessToken:default.json\n```\n\nYou can invalidate the cached function entry with:\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\nawait useStorage('cache').removeItem('nitro/functions:getAccessToken:default.json')\n```\n\n::note\nFor cached handlers, the cache key includes a hash of the URL path and, when using the [`varies`](#handler-only-options) option, hashes of the specified header values appended to the key.\n::\n\n::note\nResponses with HTTP status codes `>= 400` or with an undefined body are not cached. This prevents caching error responses.\n::\n\n::read-more{to=\"/docs/storage\"}\nRead more about the Nitro storage.\n::\n"
  },
  {
    "path": "docs/1.docs/8.storage.md",
    "content": "---\nicon: carbon:datastore\n---\n\n# KV Storage\n\n> Nitro provides a built-in storage layer that can abstract filesystem or database or any other data source.\n\nNitro has built-in integration with [unstorage](https://unstorage.unjs.io) to provide a runtime agnostic persistent layer.\n\n## Usage\n\nTo use the storage layer, you can use the `useStorage()` utility to access the storage instance.\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\n// Default storage (in-memory)\nawait useStorage().setItem(\"test:foo\", { hello: \"world\" });\nconst value = await useStorage().getItem(\"test:foo\");\n\n// You can specify a base prefix with useStorage(base)\nconst testStorage = useStorage(\"test\");\nawait testStorage.setItem(\"foo\", { hello: \"world\" });\nawait testStorage.getItem(\"foo\"); // { hello: \"world\" }\n\n// You can use generics to type the return value\nawait useStorage<{ hello: string }>(\"test\").getItem(\"foo\");\nawait useStorage(\"test\").getItem<{ hello: string }>(\"foo\");\n```\n\n:read-more{to=\"https://unstorage.unjs.io\"}\n\n### Available methods\n\nThe storage instance returned by `useStorage()` provides the following methods:\n\n| Method | Description |\n|---|---|\n| `getItem(key)` | Get the value of a key. Returns `null` if the key does not exist. |\n| `getItems(items)` | Get multiple items at once. Accepts an array of keys or `{ key, options }` objects. |\n| `getItemRaw(key)` | Get the raw value of a key without parsing. Useful for binary data. |\n| `setItem(key, value)` | Set the value of a key. |\n| `setItems(items)` | Set multiple items at once. Accepts an array of `{ key, value }` objects. |\n| `setItemRaw(key, value)` | Set the raw value of a key without serialization. |\n| `hasItem(key)` | Check if a key exists. Returns a boolean. |\n| `removeItem(key)` | Remove a key from storage. |\n| `getKeys(base?)` | Get all keys, optionally filtered by a base prefix. |\n| `clear(base?)` | Clear all keys, optionally filtered by a base prefix. |\n| `getMeta(key)` | Get metadata for a key (e.g., `mtime`, `atime`, `ttl`). |\n| `setMeta(key, meta)` | Set metadata for a key. |\n| `removeMeta(key)` | Remove metadata for a key. |\n| `mount(base, driver)` | Dynamically mount a storage driver at a base path. |\n| `unmount(base)` | Unmount a storage driver from a base path. |\n| `watch(callback)` | Watch for changes. Callback receives `(event, key)` where event is `\"update\"` or `\"remove\"`. |\n| `unwatch()` | Stop watching for changes. |\n\nShorthand aliases are also available: `get`, `set`, `has`, `del`, `remove`, `keys`.\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\n// Get all keys under a prefix\nconst keys = await useStorage(\"test\").getKeys();\n\n// Check if a key exists\nconst exists = await useStorage().hasItem(\"test:foo\");\n\n// Remove a key\nawait useStorage().removeItem(\"test:foo\");\n\n// Get raw binary data\nconst raw = await useStorage().getItemRaw(\"assets/server:image.png\");\n\n// Get metadata (type, etag, mtime, etc.)\nconst meta = await useStorage(\"assets/server\").getMeta(\"file.txt\");\n```\n\n## Configuration\n\nYou can mount one or multiple custom storage drivers using the `storage` option.\n\nThe key is the mount point name, and the value is the driver name and configuration.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    redis: {\n      driver: \"redis\",\n      /* redis connector options */\n    }\n  }\n})\n```\n\nThen, you can use the redis storage using the `useStorage(\"redis\")` function.\n\n::read-more{to=\"https://unstorage.unjs.io/\"}\nYou can find the driver list on [unstorage documentation](https://unstorage.unjs.io/) with their configuration.\n::\n\n### Development storage\n\nYou can use the `devStorage` option to override storage configuration during development and prerendering.\n\nThis is useful when your production driver is not available in development (e.g., a managed Redis instance).\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  storage: {\n    db: {\n      driver: \"redis\",\n      host: \"prod.example.com\",\n    }\n  },\n  devStorage: {\n    db: {\n      driver: \"fs\",\n      base: \"./.data/db\"\n    }\n  }\n})\n```\n\nWhen running in development mode, `devStorage` mounts are merged on top of `storage` mounts, allowing you to use a local filesystem driver or an in-memory driver while developing.\n\n## Built-in mount points\n\nNitro automatically mounts the following storage paths:\n\n### `/assets`\n\nServer assets are mounted at the `/assets` base path. This mount point provides read-only access to bundled server assets (see [Server assets](#server-assets)).\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\n// Access server assets via the /assets mount\nconst content = await useStorage(\"assets/server\").getItem(\"my-file.txt\");\n```\n\n### Default (in-memory)\n\nThe root storage (without a base path) uses an in-memory driver by default. Data stored here is not persisted across restarts.\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\n// In-memory by default, not persisted\nawait useStorage().setItem(\"counter\", 1);\n```\n\nTo persist data, mount a driver with a persistent backend (e.g., `fs`, `redis`, etc.) using the `storage` configuration option.\n\n## Server assets\n\nNitro allows you to bundle files from an `assets/` directory at the root of your project. These files are accessible at runtime via the `assets/server` storage mount.\n\n```\nmy-project/\n  assets/\n    data.json\n    templates/\n      welcome.html\n  server/\n    routes/\n      index.ts\n```\n\n```ts [server/routes/index.ts]\nimport { useStorage } from \"nitro/storage\";\n\nexport default defineHandler(async () => {\n  const serverAssets = useStorage(\"assets/server\");\n\n  const keys = await serverAssets.getKeys();\n  const data = await serverAssets.getItem(\"data.json\");\n  const template = await serverAssets.getItem(\"templates/welcome.html\");\n\n  return { keys, data, template };\n});\n```\n\n### Custom asset directories\n\nYou can register additional asset directories using the `serverAssets` config option:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  serverAssets: [\n    {\n      baseName: \"templates\",\n      dir: \"./templates\",\n    }\n  ]\n})\n```\n\nCustom asset directories are accessible under `assets/<baseName>`:\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\nconst templates = useStorage(\"assets/templates\");\nconst keys = await templates.getKeys();\nconst html = await templates.getItem(\"email.html\");\n```\n\n### Asset metadata\n\nServer assets include metadata such as content type, ETag, and modification time:\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\nconst serverAssets = useStorage(\"assets/server\");\n\nconst meta = await serverAssets.getMeta(\"image.png\");\n// { type: \"image/png\", etag: \"\\\"...\\\"\", mtime: \"2024-01-01T00:00:00.000Z\" }\n\n// Useful for setting response headers\nconst raw = await serverAssets.getItemRaw(\"image.png\");\n```\n\n::note\nIn development, server assets are read directly from the filesystem. In production, they are bundled and inlined into the build output.\n::\n\n## Runtime configuration\n\nIn scenarios where the mount point configuration is not known until runtime, Nitro can dynamically add mount points during startup using [plugins](/docs/plugins).\n\n```ts [plugins/storage.ts]\nimport { useStorage } from \"nitro/storage\";\nimport { definePlugin } from \"nitro\";\nimport redisDriver from \"unstorage/drivers/redis\";\n\nexport default definePlugin(() => {\n  const storage = useStorage()\n\n  // Dynamically pass in credentials from runtime configuration, or other sources\n  const driver = redisDriver({\n    base: \"redis\",\n    host: process.env.REDIS_HOST,\n    port: process.env.REDIS_PORT,\n    /* other redis connector options */\n  })\n\n  // Mount driver\n  storage.mount(\"redis\", driver)\n})\n```\n\n::warning\nThis is a temporary workaround, with a better solution coming in the future! Keep a lookout on the GitHub issue [here](https://github.com/nitrojs/nitro/issues/1161#issuecomment-1511444675).\n::\n"
  },
  {
    "path": "docs/1.docs/99.migration.md",
    "content": "---\nicon: ri:arrow-right-up-line\n---\n\n# Migration Guide\n\n> [!NOTE]\n> This is a living document for migrating from Nitro 2 to 3. Please check it regularly while using the beta version.\n\nNitro v3 introduces intentional backward-incompatible changes. This guide helps you migrate from Nitro v2.\n\n## `nitropack` is renamed to `nitro`\n\nThe NPM package [nitropack](https://www.npmjs.com/package/nitropack) (v2) has been renamed to [nitro](https://www.npmjs.com/package/nitro) (v3).\n\n**Migration:** Update the `nitropack` dependency to `nitro` in `package.json`:\n\n```diff [release channel]\n{\n  \"dependencies\": {\n--    \"nitropack\": \"latest\"\n++    \"nitro\": \"latest\"\n  }\n}\n```\n```diff [nightly channel]\n{\n  \"dependencies\": {\n--    \"nitropack\": \"latest\"\n++    \"nitro\": \"npm:nitro-nightly\"\n  }\n}\n```\n\n**Migration:** Search your codebase and rename all instances of nitropack to nitro:\n\n```diff\n-- import { defineNitroConfig } from \"nitropack/config\"\n++ import { defineNitroConfig } from \"nitro/config\"\n```\n\n## nitro/runtime\n\nRuntime utils had been moved to individual `nitro/*` subpath exports. Refer to docs for usage.\n\n```diff\n-- import { useStorage } from \"nitropack/runtime/storage\"\n++ import { useStorage } from \"nitro/storage\"\n```\n\n## Minimum Supported Node.js Version: 20\n\nNitro now requires a minimum Node.js version of 20, as Node.js 18 reaches end-of-life in [April 2025](https://nodejs.org/en/about/previous-releases).\n\nPlease upgrade to the [latest LTS](https://nodejs.org/en/download) version (>= 20).\n\n**Migration:**\n\n- Check your local Node.js version using `node --version` and update if necessary.\n- If you use a CI/CD system for deployment, ensure that your pipeline is running Node.js 20 or higher.\n- If your hosting provider manages the Node.js runtime, make sure it's set to version 20, 22, or later.\n\n## Type Imports\n\nNitro types are now only exported from `nitro/types`.\n\n**Migration:** Import types from nitro/types instead of nitro:\n\n```diff\n-- import { NitroRuntimeConfig } from \"nitropack\"\n++ import { NitroRuntimeConfig } from \"nitro/types\"\n```\n\n## App Config Support Removed\n\nNitro v2 supported a bundled app config that allowed defining configurations in `app.config.ts` and accessing them at runtime via `useAppConfig()`.\n\nThis feature had been removed.\n\n**Migration:**\n\nUse a regular `.ts` file in your server directory and import it directly.\n\n## Preset updates\n\nNitro presets have been updated for the latest compatibility.\n\nSome (legacy) presets have been removed or renamed.\n\n| Old Preset                   | New Preset                    |\n|------------------------------|-------------------------------|\n| `node`                       | `node_middleware` (export changed to `middleware`) |\n| `cloudflare`, `cloudflare_worker`, `cloudflare_module_legacy` | `cloudflare_module`           |\n| `deno-server-legacy`         | `deno_server` with Deno v2    |\n| `netlify-builder`            | `netlify` or `netlify_edge`   |\n| `vercel-edge`                | `vercel` with Fluid compute enabled |\n| `azure`, `azure_functions`   | `azure_swa`                   |\n| `firebase`                   | `firebase_app_hosting`        |\n| `iis`                        | `iis_handler`                 |\n| `deno`                       | `deno_deploy`                 |\n| `edgio`                      | Discontinued     |\n| `cli`                        | Removed due to lack of use |\n| `service_worker`             | Removed due to instability |\n\n## Cloudflare Bindings Access\n\nIn Nitro v2, Cloudflare environment variables and bindings were accessible via `event.context.cloudflare.env`.\n\nIn Nitro v3, the Cloudflare runtime context is attached to the request's runtime object instead.\n\n**Migration:**\n\n```diff\n-- const { cloudflare } = event.context\n-- const binding = cloudflare.env.MY_BINDING\n++ const { env } = event.req.runtime.cloudflare\n++ const binding = env.MY_BINDING\n```\n\n## Changed nitro subpath imports\n\nNitro v2 introduced multiple subpath exports, some of which have been removed or updated:\n\n- `nitro/rollup`, `nitropack/core` (use `nitro/builder`)\n- `nitropack/runtime/*` (use `nitro/*`)\n- `nitropack/kit` (removed)\n- `nitropack/presets` (removed)\n\nAn experimental `nitropack/kit` was introduced but has now been removed. A standalone Nitro Kit package may be introduced in the future with clearer objectives.\n\n**Migration:**\n\n- Use `NitroModule` from `nitro/types` instead of `defineNitroModule` from the kit.\n- Prefer built-in Nitro presets (external presets are only for evaluation purposes).\n\n## H3 v2\n\nNitro v3 upgrades to [H3 v2](https://h3.dev), which includes API changes. All H3 utilities are imported from `nitro/h3`.\n\n### Web Standards\n\nH3 v2 is rewritten based on web standard primitives ([`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL), [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers), [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request), and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)).\n\nAccess to `event.node.{req,res}` is only available in Node.js runtime. `event.web` is renamed to `event.req` (instance of web [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)).\n\n### Response Handling\n\nYou should always explicitly **return** the response body or **throw** an error:\n\n```diff\n-- import { send, sendRedirect, sendStream } from \"nitro/h3\"\n-- send(event, value)\n-- sendStream(event, stream)\n-- sendRedirect(event, location, code)\n++ import { redirect } from \"nitro/h3\"\n++ return value\n++ return stream\n++ return redirect(event, location, code)\n```\n\nOther changes:\n\n- `sendError(event, error)` → `throw createError(error)`\n- `sendNoContent(event)` → `return noContent(event)`\n- `sendProxy(event, target)` → `return proxy(event, target)`\n\n### Request Body\n\nMost body utilities can be replaced with native `event.req` methods:\n\n```diff\n-- import { readBody, readRawBody, readFormData } from \"nitro/h3\"\n++ // Use native Request methods\n++ const json = await event.req.json()\n++ const text = await event.req.text()\n++ const formData = await event.req.formData()\n++ const stream = event.req.body\n```\n\n### Headers\n\nH3 now uses standard web [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers). Header values are always plain `string` (no `null`, `undefined`, or `string[]`).\n\n```diff\n-- import { getHeader, setHeader, getResponseStatus } from \"nitro/h3\"\n-- getHeader(event, \"x-foo\")\n-- setHeader(event, \"x-foo\", \"bar\")\n++ event.req.headers.get(\"x-foo\")\n++ event.res.headers.set(\"x-foo\", \"bar\")\n++ event.res.status // instead of getResponseStatus(event)\n```\n\n### Handler Utils\n\n```diff\n-- import { eventHandler, defineEventHandler } from \"nitro/h3\"\n++ import { defineHandler } from \"nitro\"\n```\n\n- `lazyEventHandler` → `defineLazyEventHandler`\n- `useBase` → `withBase`\n\n### Error Utils\n\n```diff\n-- import { createError, isError } from \"nitro/h3\"\n++ import { HTTPError } from \"nitro\"\n++ throw new HTTPError({ status: 404, message: \"Not found\" })\n++ HTTPError.isError(error)\n```\n\n### Node.js Utils\n\n```diff\n-- import { defineNodeListener, fromNodeMiddleware, toNodeListener } from \"nitro/h3\"\n++ import { defineNodeHandler, fromNodeHandler, toNodeHandler } from \"nitro/h3\"\n```\n\n## Optional Hooks\n\nIf you were using `useNitroApp().hooks` outside of Nitro plugins before, it might be undefined. Use new `useNitroHooks()` to guarantee having an instance.\n"
  },
  {
    "path": "docs/1.docs/99.nightly.md",
    "content": "---\nicon: ri:moon-fill\n---\n\n# Nightly Channel\n\n> Nitro has a nightly release channel that automatically releases for every commit to `main` branch to try latest changes.\n\nYou can opt-in to the nightly release channel by updating your `package.json`:\n\n```json\n{\n  \"devDependencies\": {\n    \"nitro\": \"npm:nitro-nightly@latest\"\n  }\n}\n```\n\nRemove the lockfile (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lock`, or `bun.lockb`) and reinstall the dependencies.\n\n\n\n::important\nWhen using **Bun as package manager** in a mono-repo, you need to make sure nitro package is properly hoisted.\n\n<br>\n\n```toml [bunfig.toml]\n[install]\npublicHoistPattern = [\"nitro*\"]\n```\n\n::\n\n\n::important\nAvoid using `<npm|pnpm|yarn|bun|deno> install nitro-nightly`; it does not install correctly.\nIf you encounter issues, delete your `node_modules` and lock files, then follow the steps above.\n::\n"
  },
  {
    "path": "docs/2.deploy/0.index.md",
    "content": "---\nicon: ri:upload-cloud-2-line\n---\n\n# Deploy\n\n> Learn more about Nitro deploy providers.\n\nNitro can generate different output formats suitable for different hosting providers from the same code base.\nUsing built-in presets, you can easily configure Nitro to adjust its output format with almost no additional code or configuration!\n\n## Default output\n\nThe default production output preset is [Node.js server](/deploy/runtimes/node).\n\nWhen running Nitro in development mode, Nitro will always use a special preset called `nitro-dev` using Node.js with ESM in an isolated Worker environment with behavior as close as possible to the production environment.\n\n## Zero-Config Providers\n\nWhen deploying to production using CI/CD, Nitro tries to automatically detect the provider environment and set the right one without any additional configuration required. Currently, the providers below can be auto-detected with zero config.\n\n- [aws amplify](/deploy/providers/aws-amplify)\n- [azure](/deploy/providers/azure)\n- [cloudflare](/deploy/providers/cloudflare)\n- [firebase app hosting](/deploy/providers/firebase#firebase-app-hosting)\n- [netlify](/deploy/providers/netlify)\n- [stormkit](/deploy/providers/stormkit)\n- [vercel](/deploy/providers/vercel)\n- [zeabur](/deploy/providers/zeabur)\n\n::warning\nFor Turborepo users, zero config detection will be interferenced by its Strict Environment Mode. You may need to allowing the variables explictly or use its Loose Environment Mode (with `--env-mode=loose` flag).\n::\n\nOther built-in providers are available with an explicit preset, including [zephyr](/deploy/providers/zephyr).\n\n## Changing the deployment preset\n\nIf you need to build Nitro against a specific provider, you can target it by defining an environment variable named `NITRO_PRESET` or `SERVER_PRESET`, or by updating your Nitro [configuration](/docs/configuration) or using `--preset` argument.\n\nUsing the environment variable approach is recommended for deployments depending on CI/CD.\n\n**Example:** Defining a `NITRO_PRESET` environment variable\n```bash\nnitro build --preset cloudflare_pages\n```\n\n**Example:** Updating the `nitro.config.ts` file\n\n```ts\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  preset: 'cloudflare_pages'\n})\n```\n\n## Compatibility date\n\nDeployment providers regularly update their runtime behavior. Nitro presets are updated to support these new features.\n\nTo prevent breaking existing deployments, Nitro uses compatibility dates. These dates let you lock in behavior at the project creation time. You can also opt in to future updates when ready.\n\nWhen you create a new project, the `compatibilityDate` is set to the current date. This setting is saved in your project's configuration.\n\nYou should update the compatibility date periodically. Always test your deployment thoroughly after updating. Below is a list of key dates and their effects.\n\n<!-- automd:compatDate -->\n\n\n\n<!-- /automd -->\n"
  },
  {
    "path": "docs/2.deploy/10.runtimes/1.node.md",
    "content": "---\nicon: akar-icons:node-fill\n---\n\n# Node.js\n\n> Run Nitro apps with Node.js runtime.\n\n**Preset:** `node_server`\n\nNode.js is the default nitro output preset for production builds and Nitro has native Node.js runtime support.\n\nBuild project using nitro CLI:\n\n```bash\nnitro build\n```\n\nWhen running `nitro build` with the Node server preset, the result will be an entry point that launches a ready-to-run Node server. To try output:\n\n```bash\n$ node .output/server/index.mjs\nListening on http://localhost:3000\n```\n\nYou can now deploy fully standalone `.output` directory to the hosting of your choice.\n\n### Environment Variables\n\nYou can customize server behavior using following environment variables:\n\n- `NITRO_PORT` or `PORT` (defaults to `3000`)\n- `NITRO_HOST` or `HOST`\n- `NITRO_UNIX_SOCKET` - if provided (a path to the desired socket file) the service will be served over the provided UNIX socket.\n- `NITRO_SSL_CERT` and `NITRO_SSL_KEY` - if both are present, this will launch the server in HTTPS mode. In the vast majority of cases, this should not be used other than for testing, and the Nitro server should be run behind a reverse proxy like nginx or Cloudflare which terminates SSL.\n- `NITRO_SHUTDOWN_DISABLED` - Disables the graceful shutdown feature when set to `'true'`. If it's set to `'true'`, the graceful shutdown is bypassed to speed up the development process. Defaults to `'false'`.\n- `NITRO_SHUTDOWN_SIGNALS` - Allows you to specify which signals should be handled. Each signal should be separated with a space. Defaults to `'SIGINT SIGTERM'`.\n- `NITRO_SHUTDOWN_TIMEOUT` - Sets the amount of time (in milliseconds) before a forced shutdown occurs. Defaults to `'30000'` milliseconds.\n- `NITRO_SHUTDOWN_FORCE` - When set to true, it triggers `process.exit()` at the end of the shutdown process. If it's set to `'false'`, the process will simply let the event loop clear. Defaults to `'true'`.\n\n## Cluster mode\n\n**Preset:** `node_cluster`\n\nFor more performance and leveraging multi-core handling, you can use cluster preset.\n\n### Environment Variables\n\nIn addition to environment variables from the `node_server` preset, you can customize behavior:\n\n- `NITRO_CLUSTER_WORKERS`: Number of cluster workers (default is Number of available cpu cores)\n\n## Handler (advanced)\n\n**Preset:** `node_middleware`\n\nNitro also has a more low-level preset that directly exports a middleware usable for custom servers.\n\nWhen running `nitro build` with the Node middleware preset, the result will be an entry point exporting a middleware handler.\n\n**Example:**\n\n```js\nimport { createServer } from 'node:http'\nimport { listener } from './.output/server'\n\nconst server = createServer(listener)\nserver.listen(8080)\n```\n"
  },
  {
    "path": "docs/2.deploy/10.runtimes/bun.md",
    "content": "---\nicon: simple-icons:bun\n---\n\n# Bun\n\n> Run Nitro apps with Bun runtime.\n\n**Preset:** `bun`\n\nNitro output is compatible with Bun runtime. While using default [Node.js](/deploy/runtimes/node) you can also run the output in bun, using `bun` preset has advantage of better optimizations.\n\nAfter building with bun preset using `bun` as preset, you can run server in production using:\n\n```bash\nbun run ./.output/server/index.mjs\n```\n\n:read-more{to=\"https://bun.sh\"}\n"
  },
  {
    "path": "docs/2.deploy/10.runtimes/deno.md",
    "content": "---\nicon: simple-icons:deno\n---\n\n# Deno\n\n> Run Nitro apps with [Deno](https://deno.com/) runtime.\n\n**Preset:** `deno_server`\n\nYou can build your Nitro server using Node.js to run within [Deno Runtime](https://deno.com/runtime) in a custom server.\n\n```bash\n# Build with the deno NITRO preset\nNITRO_PRESET=deno_server npm run build\n\n# Start production server\ndeno run --unstable --allow-net --allow-read --allow-env .output/server/index.ts\n```\n\n## Deno Deploy\n\n:read-more{to=\"/deploy/providers/deno-deploy\"}\n"
  },
  {
    "path": "docs/2.deploy/20.providers/alwaysdata.md",
    "content": "# Alwaysdata\n\n> Deploy Nitro apps to alwaysdata.\n\n**Preset:** `alwaysdata`\n\n:read-more{to=\"https://alwaysdata.com\"}\n\n## Set up application\n\n### Pre-requisites\n\n1. [Register a new profile](https://www.alwaysdata.com/en/register/) on alwaysdata platform if you don't have one.\n\n2. Get a free 100Mb plan to host your app.\n\n> [!NOTE]\n> Keep in mind your *account name* will be used to provide you a default URL in the form of `account_name.alwaysdata.net`, so choose it wisely. You can also link your existing domains to your account later or register as many accounts under your profile as you need.\n\n### Local deployment\n\n1. Build your project locally with `npm run build -- preset alwaysdata`\n\n2. [Upload your app](https://help.alwaysdata.com/en/remote-access/) to your account in its own directory (e.g. `$HOME/www/my-app`). You can use any protocol you prefer (SSH/FTP/WebDAV…) to do so.\n\n3. On your admin panel, [create a new site](https://admin.alwaysdata.com/site/add/) for your app with the following features:\n   - *Addresses*: `[account_name].alwaysdata.net`\n   - *Type*: Node.js\n   - *Command*: `node .output/server/index.mjs`\n   - *Working directory*: `www/my-app` (adapt it to your deployment path)\n   - *Environment*:\n\n     ```ini\n     NITRO_PRESET=alwaysdata\n     ```\n\n   - *Node.js version*: `Default version` is fine; pick no less than `20.0.0` (you can also [set your Node.js version globally](https://help.alwaysdata.com/en/languages/nodejs/configuration/#supported-versions))\n   - *Hot restart*: `SIGHUP`\n\n   :read-more{title=\"Get more information about alwaysdata Node.js sites type\" to=\"https://help.alwaysdata.com/en/languages/nodejs\"}\n\n4. Your app is now live at `http(s)://[account_name].alwaysdata.net`.\n"
  },
  {
    "path": "docs/2.deploy/20.providers/aws-amplify.md",
    "content": "# AWS Amplify\n\n> Deploy Nitro apps to AWS Amplify Hosting.\n\n**Preset:** `aws_amplify`\n\n:read-more{title=\"AWS Amplify Hosting\" to=\"https://aws.amazon.com/amplify\"}\n\n## Deploy to AWS Amplify Hosting\n\n::tip\nIntegration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).\n::\n\n1. Login to the [AWS Amplify Hosting Console](https://console.aws.amazon.com/amplify/)\n2. Click on \"Get Started\" > Amplify Hosting (Host your web app)\n3. Select and authorize access to your Git repository provider and select the main branch\n4. Choose a name for your app, make sure build settings are auto-detected and optionally set requirement environment variables under the advanced section\n5. Optionally, select Enable SSR logging to enable server-side logging to your Amazon CloudWatch account\n6. Confirm configuration and click on \"Save and Deploy\"\n\n## Advanced Configuration\n\nYou can configure advanced options of this preset using `awsAmplify` option.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  awsAmplify: {\n      // catchAllStaticFallback: true,\n      // imageOptimization: { path: \"/_image\", cacheControl: \"public, max-age=3600, immutable\" },\n      // imageSettings: { ... },\n      // runtime: \"nodejs18.x\", // default: \"nodejs18.x\" | \"nodejs16.x\" | \"nodejs20.x\"\n  }\n})\n```\n\n### `amplify.yml`\n\nYou might need a custom `amplify.yml` file for advanced configuration. Here are two template examples:\n\n::code-group\n\n```yml [amplify.yml]\nversion: 1\nfrontend:\n  phases:\n    preBuild:\n      commands:\n        - nvm use 18 && node --version\n        - corepack enable && npx --yes nypm install\n    build:\n      commands:\n        - pnpm build\n  artifacts:\n    baseDirectory: .amplify-hosting\n    files:\n      - \"**/*\"\n```\n\n```yml [amplify.yml (monorepo)]\nversion: 1\napplications:\n  - frontend:\n      phases:\n        preBuild:\n          commands:\n          - nvm use 18 && node --version\n          - corepack enable && npx --yes nypm install\n        build:\n          commands:\n            - pnpm --filter website1 build\n      artifacts:\n        baseDirectory: apps/website1/.amplify-hosting\n        files:\n          - '**/*'\n      buildPath: /\n    appRoot: apps/website1\n```\n\n::\n"
  },
  {
    "path": "docs/2.deploy/20.providers/aws.md",
    "content": "# AWS Lambda\n\n> Deploy Nitro apps to AWS Lambda.\n\n**Preset:** `aws_lambda`\n\n:read-more{title=\"AWS Lambda\" to=\"https://aws.amazon.com/lambda/\"}\n\nNitro provides a built-in preset to generate output format compatible with [AWS Lambda](https://aws.amazon.com/lambda/).\nThe output entrypoint in `.output/server/index.mjs` is compatible with [AWS Lambda format](https://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html).\n\nIt can be used programmatically or as part of a deployment.\n\n```ts\nimport { handler } from './.output/server'\n\n// Use programmatically\nconst { statusCode, headers, body } = handler({ rawPath: '/' })\n```\n\n## Inlining chunks\n\nNitro output, by default uses dynamic chunks for lazy loading code only when needed. However this sometimes can not be ideal for performance. (See discussions in [nitrojs/nitro#650](https://github.com/nitrojs/nitro/pull/650)). You can enabling chunk inlining behavior using [`inlineDynamicImports`](/config#inlinedynamicimports) config.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  inlineDynamicImports: true\n});\n```\n\n\n## Response streaming\n\n:read-more{title=\"Introducing AWS Lambda response streaming\" to=\"https://aws.amazon.com/blogs/compute/introducing-aws-lambda-response-streaming/\"}\n\nIn order to enable response streaming, enable `awsLambda.streaming` flag:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  awsLambda: {\n    streaming: true\n  }\n});\n```\n"
  },
  {
    "path": "docs/2.deploy/20.providers/azure.md",
    "content": "# Azure\n\n> Deploy Nitro apps to Azure Static Web apps or functions.\n\n## Azure static web apps\n\n**Preset:** `azure-swa`\n\n:read-more{title=\"Azure Static Web Apps\" to=\"https://azure.microsoft.com/en-us/products/app-service/static\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).\n::\n\n[Azure Static Web Apps](https://azure.microsoft.com/en-us/products/app-service/static) are designed to be deployed continuously in a [GitHub Actions workflow](https://docs.microsoft.com/en-us/azure/static-web-apps/github-actions-workflow). By default, Nitro will detect this deployment environment and enable the `azure` preset.\n\n### Local preview\n\nInstall [Azure Functions Core Tools](https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local) if you want to test locally.\n\nYou can invoke a development environment to preview before deploying.\n\n```bash\nNITRO_PRESET=azure npx nypm@latest build\nnpx @azure/static-web-apps-cli start .output/public --api-location .output/server\n```\n\n### Configuration\n\nAzure Static Web Apps are [configured](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration) using the `staticwebapp.config.json` file.\n\nNitro automatically generates this configuration file whenever the application is built with the `azure` preset.\n\nNitro will automatically add the following properties based on the following criteria:\n| Property | Criteria | Default |\n| --- | --- | --- |\n| **[platform.apiRuntime](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#platform)** | Will automatically set to `node:16` or `node:14` depending on your package configuration. | `node:16` |\n| **[navigationFallback.rewrite](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#fallback-routes)** | Is always `/api/server` | `/api/server` |\n| **[routes](https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#routes)** | All prerendered routes are added. Additionally, if you do not have an `index.html` file an empty one is created for you for compatibility purposes and also requests to `/index.html` are redirected to the root directory which is handled by `/api/server`.  | `[]` |\n\n### Custom configuration\n\nYou can alter the Nitro generated configuration using `azure.config` option.\n\nCustom routes will be added and matched first. In the case of a conflict (determined if an object has the same route property), custom routes will override generated ones.\n\n### Deploy from CI/CD via GitHub actions\n\nWhen you link your GitHub repository to Azure Static Web Apps, a workflow file is added to the repository.\n\nWhen you are asked to select your framework, select custom and provide the following information:\n\n| Input | Value |\n| --- | --- |\n| **app_location** | '/' |\n| **api_location** | '.output/server' |\n| **output_location** | '.output/public' |\n\nIf you miss this step, you can always find the build configuration section in your workflow and update the build configuration:\n\n```yaml [.github/workflows/azure-static-web-apps-<RANDOM_NAME>.yml]\n###### Repository/Build Configurations ######\napp_location: '/'\napi_location: '.output/server'\noutput_location: '.output/public'\n###### End of Repository/Build Configurations ######\n```\n\nThat's it! Now Azure Static Web Apps will automatically deploy your Nitro-powered application on push.\n\nIf you are using runtimeConfig, you will likely want to configure the corresponding [environment variables on Azure](https://docs.microsoft.com/en-us/azure/static-web-apps/application-settings).\n\n"
  },
  {
    "path": "docs/2.deploy/20.providers/cleavr.md",
    "content": "# Cleavr\n\n> Deploy Nitro apps to Cleavr.\n\n**Preset:** `cleavr`\n\n:read-more{title=\"cleavr.io\" to=\"https://cleavr.io\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).\n::\n\n## Set up your web app\n\nIn your project, set Nitro preset to `cleavr`.\n\n```js\nexport default {\n  nitro: {\n    preset: 'cleavr'\n  }\n}\n```\n\nPush changes to your code repository.\n\n**In your Cleavr panel:**\n\n1. Provision a new server\n2. Add a website, selecting **Nuxt 3** as the app type\n3. In web app > settings > Code Repo, point to your project's code repository\n\nYou're now all set to deploy your project!\n"
  },
  {
    "path": "docs/2.deploy/20.providers/cloudflare.md",
    "content": "# Cloudflare\n\n> Deploy Nitro apps to Cloudflare.\n\n## Cloudflare Workers\n\n**Preset:** `cloudflare_module`\n\n:read-more{title=\"Cloudflare Workers\" to=\"https://developers.cloudflare.com/workers/\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy#zero-config-providers) supporting [workers builds (beta)](https://developers.cloudflare.com/workers/ci-cd/builds/).\n::\n\n::important\nTo use Workers with Static Assets, you need a Nitro compatibility date set to `2024-09-19` or later.\n::\n\nThe following shows an example `nitro.config.ts` file for deploying a Nitro app to Cloudflare Workers.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n    compatibilityDate: \"2024-09-19\",\n    preset: \"cloudflare_module\",\n    cloudflare: {\n      deployConfig: true,\n      nodeCompat: true\n    }\n})\n```\n\nBy setting `deployConfig: true`, Nitro will automatically generate a `wrangler.json` for you with the correct configuration.\nIf you need to add [Cloudflare Workers configuration](https://developers.cloudflare.com/workers/wrangler/configuration/), such as [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/), you can either:\n\n- Set these in your Nitro config under the `cloudflare: { wrangler : {} }`. This has the same type as `wrangler.json`.\n- Provide your own `wrangler.json`. Nitro will merge your config with the appropriate settings, including pointing to the build output.\n\n### Local Preview\n\nYou can use [Wrangler](https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler) to preview your app locally:\n\n:pm-run{script=\"build\"}\n\n:pm-x{command=\"wrangler dev\"}\n\n### Manual Deploy\n\nAfter having built your application you can manually deploy it with Wrangler.\n\nFirst make sure to be logged into your Cloudflare account:\n\n:pm-x{command=\"wrangler login\"}\n\nThen you can deploy the application with:\n\n:pm-x{command=\"wrangler deploy\"}\n\n### Runtime Hooks\n\nYou can use [runtime hooks](/docs/plugins#nitro-runtime-hooks) below in order to extend [Worker handlers](https://developers.cloudflare.com/workers/runtime-apis/handlers/).\n\n:read-more{to=\"/docs/plugins#nitro-runtime-hooks\"}\n\n- [`cloudflare:scheduled`](https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/)\n- [`cloudflare:email`](https://developers.cloudflare.com/email-routing/email-workers/runtime-api/)\n- [`cloudflare:queue`](https://developers.cloudflare.com/queues/configuration/javascript-apis/#consumer)\n- [`cloudflare:tail`](https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/)\n- `cloudflare:trace`\n\n### Additional Exports\n\nYou can add a `exports.cloudflare.ts` file to your project root to export additional handlers or properties to the Cloudflare Worker entrypoint.\n\n```ts [exports.cloudflare.ts]\nexport class MyWorkflow extends WorkflowEntrypoint {\n  async run(event: WorkflowEvent, step: WorkflowStep) {\n    // ...\n  }\n}\n```\n\nNitro will automatically detect this file and include its exports in the final build.\n\n::warning\nThe `exports.cloudflare.ts` file must not have a default export.\n::\n\nYou can also customize the entrypoint file location using the `cloudflare.exports` option in your `nitro.config.ts`:\n\n```ts [nitro.config.ts]\nexport default defineConfig({\n  cloudflare: {\n    exports: \"custom-exports-entry.ts\"\n  }\n})\n```\n\n### Scheduled Tasks (Cron Triggers)\n\nWhen using [Nitro tasks](/docs/tasks) with `scheduledTasks`, Nitro automatically generates [Cron Triggers](https://developers.cloudflare.com/workers/configuration/cron-triggers/) in the wrangler config at build time.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  preset: \"cloudflare_module\",\n  experimental: {\n    tasks: true,\n  },\n  scheduledTasks: {\n    \"* * * * *\": [\"cms:update\"],\n    \"0 15 1 * *\": [\"db:cleanup\"],\n  },\n  cloudflare: {\n    deployConfig: true,\n  },\n})\n```\n\nNo manual Wrangler configuration is needed - Nitro handles it for you.\n\n## Cloudflare Pages\n\n**Preset:** `cloudflare_pages`\n\n:read-more{title=\"Cloudflare Pages\" to=\"https://pages.cloudflare.com/\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy#zero-config-providers).\n::\n\n::warning\nCloudflare [Workers Module](#cloudflare-workers) is the new recommended preset for deployments. Please consider using the pages only if you need specific features.\n::\n\nThe following shows an example `nitro.config.ts` file for deploying a Nitro app to Cloudflare Pages.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n    preset: \"cloudflare_pages\",\n    cloudflare: {\n      deployConfig: true,\n      nodeCompat:true\n    }\n})\n```\n\nNitro automatically generates a `_routes.json` file that controls which routes get served from files and which are served from the Worker script. The auto-generated routes file can be overridden with the config option `cloudflare.pages.routes` ([read more](https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes)).\n\n### Local Preview\n\nYou can use [Wrangler](https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler) to preview your app locally:\n\n:pm-run{script=\"build\"}\n\n:pm-x{command=\"wrangler pages dev\"}\n\n### Manual Deploy\n\nAfter having built your application you can manually deploy it with Wrangler, in order to do so first make sure to be\nlogged into your Cloudflare account:\n\n:pm-x{command=\"wrangler login\"}\n\nThen you can deploy the application with:\n\n:pm-x{command=\"wrangler pages deploy\"}\n\n\n## Deploy within CI/CD using GitHub Actions\n\nRegardless on whether you're using Cloudflare Pages or Cloudflare Workers, you can use the [Wrangler GitHub actions](https://github.com/marketplace/actions/deploy-to-cloudflare-workers-with-wrangler) to deploy your application.\n\n::note\n**Note:** Remember to [instruct Nitro to use the correct preset](/deploy#changing-the-deployment-preset) (note that this is necessary for all presets including the `cloudflare_pages` one).\n::\n\n## Environment Variables\n\nNitro allows you to universally access environment variables using `process.env` or `import.meta.env` or the runtime config.\n\n::note\nMake sure to only access environment variables **within the event lifecycle**  and not in global contexts since Cloudflare only makes them available during the request lifecycle and not before.\n::\n\n**Example:** If you have set the `SECRET` and `NITRO_HELLO_THERE` environment variables set you can access them in the following way:\n\n```ts\nimport { defineHandler } from \"nitro\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nconsole.log(process.env.SECRET) // note that this is in the global scope! so it doesn't actually work and the variable is undefined!\n\nexport default defineHandler((event) => {\n  // note that all the below are valid ways of accessing the above mentioned variables\n  useRuntimeConfig().helloThere\n  useRuntimeConfig().secret\n  process.env.NITRO_HELLO_THERE\n  import.meta.env.SECRET\n});\n```\n\n### Specify Variables in Development Mode\n\nFor development, you can use a `.env` or `.env.local` file to specify environment variables:\n\n```ini\nNITRO_HELLO_THERE=\"captain\"\nSECRET=\"top-secret\"\n```\n\n::note\n**Note:** Make sure you add `.env` and `.env.local` to the `.gitignore` file so that you don't commit it as it can contain sensitive information.\n::\n\n### Specify Variables for local previews\n\nAfter build, when you try out your project locally with `wrangler dev` or `wrangler pages dev`, in order to have access to environment variables you will need to specify the in a `.dev.vars` file in the root of your project (as presented in the [Pages](https://developers.cloudflare.com/pages/functions/bindings/#interact-with-your-environment-variables-locally) and [Workers](https://developers.cloudflare.com/workers/configuration/environment-variables/#interact-with-environment-variables-locally) documentation).\n\nIf you are using a `.env` or `.env.local` file while developing, your `.dev.vars` should be identical to it.\n\n::note\n**Note:** Make sure you add `.dev.vars` to the `.gitignore` file so that you don't commit it as it can contain sensitive information.\n::\n\n### Specify Variables for Production\n\nFor production, use the Cloudflare dashboard or the [`wrangler secret`](https://developers.cloudflare.com/workers/wrangler/commands/#secret) command to set environment variables and secrets.\n\n### Specify Variables using `wrangler.toml`/`wrangler.json`\n\nYou can specify a custom `wrangler.toml`/`wrangler.json` file and define vars inside.\n\n::warning\nNote that this isn't recommend for sensitive data like secrets.\n::\n\n**Example:**\n\n::code-group\n\n```ini [wrangler.toml]\n# Shared\n[vars]\nNITRO_HELLO_THERE=\"general\"\nSECRET=\"secret\"\n\n# Override values for `--env production` usage\n[env.production.vars]\nNITRO_HELLO_THERE=\"captain\"\nSECRET=\"top-secret\"\n```\n\n```json [wrangler.json]\n{\n  \"vars\": {\n    \"NITRO_HELLO_THERE\": \"general\",\n    \"SECRET\": \"secret\"\n  },\n  \"env\": {\n    \"production\": {\n      \"vars\": {\n        \"NITRO_HELLO_THERE\": \"captain\",\n        \"SECRET\": \"top-secret\"\n      }\n    }\n  }\n}\n\n```\n\n::\n\n## Direct access to Cloudflare bindings\n\nBindings are what allows you to interact with resources from the Cloudflare platform, examples of such resources are key-value data storages ([KVs](https://developers.cloudflare.com/kv/)) and serverless SQL databases ([D1s](https://developers.cloudflare.com/d1/)).\n\n::read-more\nFor more details on Bindings and how to use them please refer to the Cloudflare [Pages](https://developers.cloudflare.com/pages/functions/bindings/) and [Workers](https://developers.cloudflare.com/workers/configuration/bindings/#bindings) documentation.\n::\n\n> [!TIP]\n> Nitro provides high level API to interact with primitives such as [KV Storage](/docs/storage) and [Database](/docs/database) and you are highly recommended to prefer using them instead of directly depending on low-level APIs for usage stability.\n\n:read-more{title=\"Database Layer\" to=\"/docs/database\"}\n\n:read-more{title=\"KV Storage\" to=\"/docs/storage\"}\n\nIn runtime, you can access bindings from the request event via `event.req.runtime.cloudflare.env`. This is for example how you can access a D1 binding:\n\n```ts\nimport { defineHandler } from \"nitro\";\n\ndefineHandler(async (event) => {\n  const { env } = event.req.runtime.cloudflare\n  const stmt = await env.MY_D1.prepare('SELECT id FROM table')\n  const { results } = await stmt.all()\n})\n```\n\n### Access to the bindings in local dev\n\nTo access bindings in dev mode, we first define them. You can do this in a `wrangler.jsonc`/`wrangler.json`/`wrangler.toml` file\n\nFor example, to define a variable and a KV namespace in `wrangler.toml`:\n\n::code-group\n\n```ini [wrangler.toml]\n[vars]\nMY_VARIABLE=\"my-value\"\n\n[[kv_namespaces]]\nbinding = \"MY_KV\"\nid = \"xxx\"\n```\n\n```json [wrangler.json]\n{\n  \"vars\": {\n    \"MY_VARIABLE\": \"my-value\",\n  },\n  \"kv_namespaces\": [\n    {\n      \"binding\": \"MY_KV\",\n      \"id\": \"xxx\"\n    }\n  ]\n}\n```\n\n::\n\nNext we install the required `wrangler` package (if not already installed):\n\n:pm-install{name=\"wrangler -D\"}\n\nFrom this moment, when running\n\n:pm-run{script=\"dev\"}\n\nyou will be able to access the `MY_VARIABLE` and `MY_KV` from the request event just as illustrated above.\n\n#### Wrangler environments\n\nIf you have multiple Wrangler environments, you can specify which Wrangler environment to use during Cloudflare dev emulation:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  preset: 'cloudflare_module',\n  cloudflare: {\n    dev: {\n      environment: 'preview'\n    }\n  }\n})\n```\n"
  },
  {
    "path": "docs/2.deploy/20.providers/deno-deploy.md",
    "content": "# Deno Deploy\n\n> Deploy Nitro apps to [Deno Deploy](https://deno.com/deploy).\n\n**Preset:** `deno_deploy`\n\n:read-more{title=\"Deno Deploy\" to=\"https://deno.com/deploy\"}\n\n## Deploy with the CLI\n\nYou can use [deployctl](https://deno.com/deploy/docs/deployctl) to deploy your app.\n\nLogin to [Deno Deploy](https://dash.deno.com/account#access-tokens) to obtain a `DENO_DEPLOY_TOKEN` access token, and set it as an environment variable.\n\n```bash\n# Build with the deno_deploy NITRO preset\nNITRO_PRESET=deno_deploy npm run build\n\n# Make sure to run the deployctl command from the output directory\ncd .output\ndeployctl deploy --project=my-project server/index.ts\n```\n\n## Deploy within CI/CD using GitHub actions\n\nYou just need to include the deployctl GitHub Action as a step in your workflow.\n\nYou do not need to set up any secrets for this to work. You do need to link your GitHub repository to your Deno Deploy project and choose the \"GitHub Actions\" deployment mode. You can do this in your project settings on [Deno Deploy](https://dash.deno.com).\n\nCreate the following workflow file in your `.github/workflows` directory:\n\n```yaml [.github/workflows/deno_deploy.yml]\nname: deno-deploy\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    branches:\n      - main\n\njobs:\n  deploy:\n    steps:\n      - uses: actions/checkout@v5\n      - run: corepack enable\n      - uses: actions/setup-node@v6\n        with:\n          node-version: 18\n          cache: pnpm\n      - run: pnpm install\n      - run: pnpm build\n        env:\n          NITRO_PRESET: deno_deploy\n      - name: Deploy to Deno Deploy\n        uses: denoland/deployctl@v1\n        with:\n          project: my-project\n          entrypoint: server/index.ts\n          root: .output\n```\n\n## Deno runtime\n\n:read-more{to=\"/deploy/runtimes/deno\"}\n"
  },
  {
    "path": "docs/2.deploy/20.providers/digitalocean.md",
    "content": "# DigitalOcean\n\n> Deploy Nitro apps to DigitalOcean.\n\n**Preset:** `digital_ocean`\n\n:read-more{title=\"Digital Ocean App Platform\" to=\"https://docs.digitalocean.com/products/app-platform/\"}\n\n## Set up application\n\n1. Create a new Digital Ocean app following the [guide](https://docs.digitalocean.com/products/app-platform/how-to/create-apps/).\n\n1. Next, you'll need to configure environment variables. In your app settings, ensure the following app-level environment variables are set:\n\n   ```bash\n   NITRO_PRESET=digital_ocean\n   ```\n\n   [More information](https://docs.digitalocean.com/products/app-platform/how-to/use-environment-variables/).\n\n1. You will need to ensure you set an `engines.node` field in your app's `package.json` to ensure Digital Ocean uses a supported version of Node.js:\n\n   ```json\n   {\n      \"engines\": {\n         \"node\": \"20.x\"\n      }\n   }\n   ```\n\n   [See more information](https://docs.digitalocean.com/products/app-platform/languages-frameworks/nodejs/#node-version).\n\n1. You'll also need to add a run command so Digital Ocean knows what command to run after a build. You can do so by adding a start script to your `package.json`:\n\n   ```json\n   {\n      \"scripts\": {\n         \"start\": \"node .output/server/index.mjs\"\n      }\n   }\n   ```\n\n1. Finally, you'll need to add this start script to your Digital Ocean app's run command. Go to `Components > Settings > Commands`, click \"Edit\", then add `npm run start`\n\nYour app should be live at a Digital Ocean generated URL and you can now follow [the rest of the Digital Ocean deployment guide](https://docs.digitalocean.com/products/app-platform/how-to/manage-deployments/).\n"
  },
  {
    "path": "docs/2.deploy/20.providers/firebase.md",
    "content": "# Firebase\n\n> Deploy Nitro apps to Firebase.\n\n::note\nYou will need to be on the [**Blaze plan**](https://firebase.google.com/pricing) (Pay as you go) to get started.\n::\n\n## Firebase app hosting\n\nPreset: `firebase_app_hosting`\n\n:read-more{title=\"Firebase App Hosting\" to=\"https://firebase.google.com/docs/app-hosting\"}\n\n::tip\nYou can integrate with this provider using [zero configuration](/deploy/#zero-config-providers).\n::\n\n### Project setup\n\n1. Go to the Firebase [console](https://console.firebase.google.com/) and set up a new project.\n2. Select **Build > App Hosting** from the sidebar.\n    - You may need to upgrade your billing plan at this step.\n3. Click **Get Started**.\n    - Choose a region.\n    - Import a GitHub repository (you’ll need to link your GitHub account).\n    - Configure deployment settings (project root directory and branch), and enable automatic rollouts.\n    - Choose a unique ID for your backend.\n4. Click Finish & Deploy to create your first rollout.\n\nWhen you deploy with Firebase App Hosting, the App Hosting preset will be run automatically at build time.\n"
  },
  {
    "path": "docs/2.deploy/20.providers/flightcontrol.md",
    "content": "# Flightcontrol\n\n> Deploy Nitro apps to AWS via Flightcontrol.\n\n**Preset:** `flightcontrol`\n\n:read-more{title=\"flightcontrol.dev\" to=\"https://flightcontrol.dev?ref=nitro\"}\n\n## Set Up your flightcontrol account\n\nOn a high level, the steps you will need to follow to deploy a project for the first time are:\n\n1. Create an account at [Flightcontrol](https://app.flightcontrol.dev/signup?ref=nitro)\n2. Create an account at [AWS](https://portal.aws.amazon.com/billing/signup) (if you don't already have one)\n3. Link your AWS account to the Flightcontrol\n4. Authorize the Flightcontrol GitHub App to access your chosen repositories, public or private.\n5. Create a Flightcontrol project with configuration via the Dashboard or with configuration via `flightcontrol.json`.\n\n### Create a project with configuration via the dashboard\n\n1. Create a Flightcontrol project from the Dashboard. Select a repository for the source.\n2. Select the `GUI` config type.\n3. Select the Nuxt preset. This preset will also work for any Nitro-based applications.\n4. Select your preferred AWS server size.\n5. Submit the new project form.\n\n### Create a project with configuration via `flightcontrol.json`\n\n1. Create a Flightcontrol project from your dashboard. Select a repository for the source.\n2. Select the `flightcontrol.json` config type.\n3. Add a new file at the root of your repository called `flightcontrol.json`. Here is an example configuration that creates an AWS fargate service for your app:\n\n  ```json [flightcontrol.json]\n  {\n    \"$schema\": \"https://app.flightcontrol.dev/schema.json\",\n    \"environments\": [\n      {\n        \"id\": \"production\",\n        \"name\": \"Production\",\n        \"region\": \"us-west-2\",\n        \"source\": {\n          \"branch\": \"main\"\n        },\n        \"services\": [\n          {\n            \"id\": \"nitro\",\n            \"buildType\": \"nixpacks\",\n            \"name\": \"My Nitro site\",\n            \"type\": \"fargate\",\n            \"domain\": \"www.yourdomain.com\",\n            \"outputDirectory\": \".output\",\n            \"startCommand\": \"node .output/server/index.mjs\",\n            \"cpu\": 0.25,\n            \"memory\": 0.5\n          }\n        ]\n      }\n    ]\n  }\n  ```\n\n4. Submit the new project form.\n\n::read-more{to=\"https://www.flightcontrol.dev/docs?ref=nitro\"}\nLearn more about Flightcontrol's [configuration](https://www.flightcontrol.dev/docs?ref=nitro).\n::\n"
  },
  {
    "path": "docs/2.deploy/20.providers/genezio.md",
    "content": "# Genezio\n\n> Deploy Nitro apps to Genezio.\n\n**Preset:** `genezio`\n\n:read-more{title=\"Genezio\" to=\"https://genezio.com\"}\n\n> [!IMPORTANT]\n> 🚧 This preset is currently experimental.\n\n## 1. Project Setup\n\nCreate `genezio.yaml` file:\n\n```yaml\n# The name of the project.\nname: nitro-app\n# The version of the Genezio YAML configuration to parse.\nyamlVersion: 2\nbackend:\n  # The root directory of the backend.\n  path: .output/\n  # Information about the backend's programming language.\n  language:\n      # The name of the programming language.\n      name: js\n      # The package manager used by the backend.\n      packageManager: npm\n  # Information about the backend's functions.\n  functions:\n      # The name (label) of the function.\n      - name: nitroServer\n      # The path to the function's code.\n        path: server/\n        # The name of the function handler\n        handler: handler\n        # The entry point for the function.\n        entry: index.mjs\n```\n\n::read-more{to=\"https://genezio.com/docs/project-structure/genezio-configuration-file/\"}\nTo further customize the file to your needs, you can consult the\n[official documentation](https://genezio.com/docs/project-structure/genezio-configuration-file/).\n::\n\n\n## 2. Deploy your project\n\nBuild with the genezio nitro preset:\n\n```bash\nNITRO_PRESET=genezio npm run build\n```\n\n\nDeploy with [`genezio`](https://npmjs.com/package/genezio) cli:\n\n:pm-x{command=\"genezio deploy\"}\n\n::read-more{title=\"Backend Environment Variables\" to=\"https://genezio.com/docs/project-structure/backend-environment-variables\"}\nTo set environment viarables, please check out [Genezio - Environment Variables](https://genezio.com/docs/project-structure/backend-environment-variables).\n::\n\n\n## 3. Monitor your project\nYou can monitor and manage your application through the [Genezio App Dashboard](https://app.genez.io/dashboard). The dashboard URL, also provided after deployment, allows you to access comprehensive views of your project's status and logs.\n\n"
  },
  {
    "path": "docs/2.deploy/20.providers/github-pages.md",
    "content": "# GitHub Pages\n\n> Deploy Nitro apps to GitHub Pages.\n\n**Preset:** `github_pages`\n\n:read-more{title=\"GitHub Pages\" to=\"https://pages.github.com/\"}\n\n## Setup\n\nFollow the steps to [create a GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site).\n\n## Deployment\n\nHere is an example GitHub Actions workflow to deploy your site to GitHub Pages using the `github_pages` preset:\n\n```yaml [.github/workflows/deploy.yml]\n# https://github.com/actions/deploy-pages#usage\nname: Deploy to GitHub Pages\n\non:\n  workflow_dispatch:\n  push:\n    branches:\n      - main\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n      - run: corepack enable\n      - uses: actions/setup-node@v6\n        with:\n          node-version: \"18\"\n\n      - run: npx nypm install\n      - run: npm run build\n        env:\n          NITRO_PRESET: github_pages\n\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v1\n        with:\n          path: ./.output/public\n\n  # Deployment job\n  deploy:\n    # Add a dependency to the build job\n    needs: build\n\n    # Grant GITHUB_TOKEN the permissions required to make a Pages deployment\n    permissions:\n      pages: write      # to deploy to Pages\n      id-token: write   # to verify the deployment originates from an appropriate source\n\n    # Deploy to the github_pages environment\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n\n    # Specify runner + deployment step\n    runs-on: ubuntu-latest\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v1\n```\n"
  },
  {
    "path": "docs/2.deploy/20.providers/gitlab-pages.md",
    "content": "# GitLab Pages\n\n> Deploy Nitro apps to GitLab Pages.\n\n**Preset:** `gitlab_pages`\n\n:read-more{title=\"GitLab Pages\" to=\"https://pages.github.com/\"}\n\n## Setup\n\nFollow the steps to [create a GitLab Pages site](https://docs.gitlab.com/ee/user/project/pages/#getting-started).\n\n## Deployment\n\n1. Here is an example GitLab Pages workflow to deploy your site to GitLab Pages:\n\n```yaml [.gitlab-ci.yml]\nimage: node:lts\nbefore_script:\n  - npx nypm install\npages:\n  cache:\n    paths:\n      - node_modules/\n  variables:\n    NITRO_PRESET: gitlab_pages\n  script:\n    - npm run build\n  artifacts:\n    paths:\n      - .output/public\n  publish: .output/public\n  rules:\n    # This ensures that only pushes to the default branch\n    # will trigger a pages deploy\n    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH\n```\n"
  },
  {
    "path": "docs/2.deploy/20.providers/heroku.md",
    "content": "# Heroku\n\n> Deploy Nitro apps to Heroku.\n\n**Preset:** `heroku`\n\n:read-more{title=\"heroku.com\" to=\"https://heroku.com/\"}\n\n## Using the heroku CLI\n\n1. Create a new Heroku app.\n\n   ```bash\n   heroku create myapp\n   ```\n\n1. Configure Heroku to use the nodejs buildpack.\n\n   ```bash\n   heroku buildpacks:set heroku/nodejs\n   ```\n\n1. Configure your app.\n\n   ```bash\n   heroku config:set NITRO_PRESET=heroku\n   ```\n\n1. Ensure you have `start` and `build` commands in your `package.json` file.\n\n   ```json5\n   \"scripts\": {\n     \"build\": \"nitro build\", // or `nuxt build` if using nuxt\n     \"start\": \"node .output/server/index.mjs\"\n   }\n   ```\n\n## With nginx\n\n1. Add the heroku Nginx buildpack [here](https://github.com/heroku/heroku-buildpack-nginx.git)\n\n1. Change to the 'node' preset in your `nitro.config`\n\n   ```json5\n   \"nitro\": {\n      \"preset\":\"node\",\n   }\n   ```\n\n1. From the **Existing app** section of buildpack doc, 2 key steps are required to get things running\n\n   Step 1: Listen on a socket at 'tmp/nginx.socket'\n   Step 2: Create a file '/tmp/app-initialized' when your app is ready to accept connections\n\n1. Create custom app runner, eg: apprunner.mjs at the root of the project (or any other preferred location), in this file, create a server, using the listener generated by the node preset, then listen on the socket as detailed in the buildpack doc\n\n   ```ts\n   import { createServer } from 'node:http'\n   import { listener } from './.output/server/index.mjs'\n\n   const server = createServer(listener)\n\n   server.listen('/tmp/nginx.socket') //following the buildpack doc\n   ```\n\n1. To create the 'tmp/app-initialized' file, use a nitro plugin, create file 'initServer.ts' at the root of the project (or any other preferred location)\n\n   ```ts\n   import fs from \"fs\"\n\n   export default definePlugin((nitroApp) => {\n      if((process.env.NODE_ENV || 'development') != 'development') {\n         fs.openSync('/tmp/app-initialized', 'w')\n      }\n   })\n   ```\n\n1. Finally, create file 'Procfile' at the root of the project, with the Procfile, we tell heroku to start nginx and use the custom apprunner.mjs to start the server\n\n   web: bin/start-nginx node apprunner.mjs\n\n1. Bonus: create file 'config/nginx.conf.erb' to customize your nginx config. With the node preset, by default, static files handlers will not be generated, you can use nginx to server static files, just add the right location rule to the server block(s), or, force the node preset to generate handlers for the static files by setting serveStatic to true.\n"
  },
  {
    "path": "docs/2.deploy/20.providers/iis.md",
    "content": "# IIS\n\n> Deploy Nitro apps to IIS.\n\n## Using [IISnode](https://github.com/Azure/iisnode)\n\n**Preset:** `iis_node`\n\n1. Install the latest LTS version of [Node.js](https://nodejs.org/en/) on your Windows Server.\n2. Install [IISnode](https://github.com/azure/iisnode/releases)\n3. Install [IIS `URLRewrite` Module](https://www.iis.net/downloads/microsoft/url-rewrite).\n4. In IIS, add `.mjs` as a new mime type and set its content type to `application/javascript`.\n5. Deploy the contents of your `.output` folder to your website in IIS.\n\n## Using IIS handler\n\n**Preset:** `iis_handler`\n\nYou can use IIS http handler directly.\n\n1. Install the latest LTS version of [Node.js](https://nodejs.org/en/) on your Windows Server.\n2. Install [IIS `HttpPlatformHandler` Module](https://www.iis.net/downloads/microsoft/httpplatformhandler)\n3. Copy your `.output` directory into the Windows Server, and create a website on IIS pointing to that exact directory.\n\n## IIS config options\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  // IIS options default\n  iis: {\n    // merges in a pre-existing web.config file to the nitro default file\n    mergeConfig: true,\n    // overrides the default nitro web.config file all together\n    overrideConfig: false,\n  },\n});\n```\n"
  },
  {
    "path": "docs/2.deploy/20.providers/koyeb.md",
    "content": "# Koyeb\n\n> Deploy Nitro apps to Koyeb.\n\n**Preset:** `koyeb`\n\n:read-more{to=\"https://www.koyeb.com\"}\n\n## Using the control panel\n\n1. In the [Koyeb control panel](https://app.koyeb.com/), click **Create App**.\n2. Choose **GitHub** as your deployment method.\n3. Choose the GitHub **repository** and **branch** containing your application code.\n4. Name your Service.\n5. If you did not add a `start` command to your `package.json` file, under the **Build and deployment settings**, toggle the override switch associated with the run command field.  In the **Run command** field, enter:\n\n   ```bash\n   node .output/server/index.mjs`\n   ```\n\n6. In the **Advanced** section, click **Add Variable** and add a `NITRO_PRESET` variable set to `koyeb`.\n7. Name the App.\n8. Click the **Deploy** button.\n\n## Using the Koyeb CLI\n\n1. Follow the instructions targeting your operating system to [install the Koyeb CLI client](https://www.koyeb.com/docs/cli/installation) with an installer.  Alternatively, visit the [releases page on GitHub](https://github.com/koyeb/koyeb-cli/releases) to directly download required files.\n2. Create a Koyeb API access token by visiting the [API settings for your organization](https://app.koyeb.com/settings/api) in the Koyeb control panel.\n3. Log into your account with the Koyeb CLI by typing:\n\n   ```bash\n   koyeb login\n   ```\n\n   Paste your API credentials when prompted.\n4. Deploy your Nitro application from a GitHub repository with the following command.  Be sure to substitute your own values for `<APPLICATION_NAME>`, `<YOUR_GITHUB_USERNAME>`, and `<YOUR_REPOSITORY_NAME>`:\n\n   ```bash\n   koyeb app init <APPLICATION_NAME> \\\n      --git github.com/<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME> \\\n      --git-branch main \\\n      --git-run-command \"node .output/server/index.mjs\" \\\n      --ports 3000:http \\\n      --routes /:3000 \\\n      --env PORT=3000 \\\n      --env NITRO_PRESET=koyeb\n   ```\n\n## Using a docker container\n\n1. Create a `.dockerignore` file in the root of your project and add the following lines:\n\n   ```\n   Dockerfile\n   .dockerignore\n   node_modules\n   npm-debug.log\n   .nitro\n   .output\n   .git\n   dist\n   README.md\n   ```\n\n2. Add a `Dockerfile` to the root of your project:\n\n   ```\n   FROM node:18-alpine AS base\n\n   FROM base AS deps\n   RUN apk add --no-cache libc6-compat\n   WORKDIR /app\n   COPY package.json package-lock.json ./\n   RUN npm ci\n\n   FROM base AS builder\n   WORKDIR /app\n   COPY --from=deps /app/node_modules ./node_modules\n   COPY . .\n   RUN npm run build && npm cache clean --force\n\n   FROM base AS runner\n   WORKDIR /app\n   RUN addgroup --system --gid 1001 nodejs\n   RUN adduser --system --uid 1001 nitro\n   COPY --from=builder /app .\n   USER nitro\n   EXPOSE 3000\n   ENV PORT 3000\n   CMD [\"npm\", \"run\", \"start\"]\n   ```\n\nThe Dockerfile above provides the minimum requirements to run the Nitro application. You can easily extend it depending on your needs.\nYou will then need to push your Docker image to a registry. You can use [Docker Hub](https://hub.docker.com/) or [GitHub Container Registry](https://docs.github.com/en/packages/guides/about-github-container-registry) for example.\nIn the Koyeb control panel, use the image and the tag field to specify the image you want to deploy.\nYou can also use the [Koyeb CLI](https://www.koyeb.com/docs/build-and-deploy/cli/installation)\nRefer to the Koyeb [Docker documentation](https://www.koyeb.com/docs/build-and-deploy/prebuilt-docker-images) for more information.\n"
  },
  {
    "path": "docs/2.deploy/20.providers/netlify.md",
    "content": "# Netlify\n\n> Deploy Nitro apps to Netlify functions or edge.\n\n**Preset:** `netlify`\n\n:read-more{title=\"Netlify Functions\" to=\"https://www.netlify.com/platform/core/functions/\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).\n::\n\nNormally, the deployment to Netlify does not require any configuration.\nNitro will auto-detect that you are in a [Netlify](https://www.netlify.com) build environment and build the correct version of your server.\n\nFor new sites, Netlify will detect that you are using Nitro and set the publish directory to `dist` and build command to `npm run build`.\n\nIf you are upgrading an existing site you should check these and update them if needed.\n\nIf you want to add custom redirects, you can do so with [`routeRules`](/config#routerules) or by adding a [`_redirects`](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file) file to your `public` directory.\n\nFor deployment, just push to your git repository [as you would normally do for Netlify](https://docs.netlify.com/configure-builds/get-started/).\n\n::note{type=\"note\"}\nMake sure the publish directory is set to `dist` when creating a new project.\n::\n\n## Netlify edge functions\n\n**Preset:** `netlify_edge`\n\nNetlify Edge Functions use Deno and the powerful V8 JavaScript runtime to let you run globally distributed functions for the fastest possible response times.\n\n:read-more{title=\"Netlify Edge functions\" to=\"https://docs.netlify.com/edge-functions/overview/\"}\n\nNitro output can directly run the server at the edge. Closer to your users.\n\n::note{type=\"note\"}\nMake sure the publish directory is set to `dist` when creating a new project.\n::\n\n## Custom deploy configuration\n\nYou can provide additional deploy configuration using the `netlify` key inside `nitro.config`. It will be merged with built-in auto-generated config. Currently the only supported value is `images.remote_images`, for [configuring Netlify Image CDN](https://docs.netlify.com/image-cdn/create-integration/).\n"
  },
  {
    "path": "docs/2.deploy/20.providers/platform-sh.md",
    "content": "# Platform.sh\n\n> Deploy Nitro apps to platform.sh\n\n**Preset:** `platform_sh`\n\n:read-more{to=\"https://platform.sh\"}\n\n## Setup\n\nFirst, create a new project on platform.sh and link it to the repository you want to auto-deploy with.\n\nThen in repository create `.platform.app.yaml` file:\n\n```yaml [.platform.app.yaml]\nname: nitro-app\ntype: 'nodejs:20'\ndisk: 128\nweb:\n  commands:\n    start: \"node .output/server/index.mjs\"\nbuild:\n  flavor: none\nhooks:\n  build: |\n    corepack enable\n    npx nypm install\n    NITRO_PRESET=platform_sh npm run build\nmounts:\n    '.data':\n        source: local\n        source_path: .data\n```\n\n:read-more{title=\"Complete list of all available properties\" to=\"https://docs.platform.sh/create-apps/app-reference.html\"}\n\n:read-more{title=\"Complete list of all available properties\" to=\"https://unjs.io/blog/2023-08-25-nitro-2.6#default-persistent-data-storage\"}\n"
  },
  {
    "path": "docs/2.deploy/20.providers/render.md",
    "content": "# Render.com\n\n> Deploy Nitro apps to Render.com.\n\n**Preset:** `render_com`\n\n:read-more{title=\"render.com\" to=\"https://render.com\"}\n\n## Set up application\n\n1. [Create a new Web Service](https://dashboard.render.com/select-repo?type=web) and select the repository that contains your code.\n2. Ensure the 'Node' environment is selected.\n3. Update the start command to `node .output/server/index.mjs`\n4. Click 'Advanced' and add an environment variable with `NITRO_PRESET` set to `render_com`. You may also need to add a `NODE_VERSION` environment variable set to `20` for the build to succeed ([docs](https://render.com/docs/node-version)).\n5. Click 'Create Web Service'.\n\n## Infrastructure as Code (IaC)\n\n1. Create a file called `render.yaml` with following content at the root of your repository.\n\n> This file followed by [Infrastructure as Code](https://render.com/docs/infrastructure-as-code) on Render\n\n```yaml\nservices:\n  - type: web\n    name: <PROJECTNAME>\n    env: node\n    branch: main\n    startCommand: node .output/server/index.mjs\n    buildCommand: npx nypm install && npm run build\n    envVars:\n    - key: NITRO_PRESET\n      value: render_com\n```\n\n1. [Create a new Blueprint Instance](https://dashboard.render.com/select-repo?type=blueprint) and select the repository containing your `render.yaml` file.\n\nYou should be good to go!\n"
  },
  {
    "path": "docs/2.deploy/20.providers/stormkit.md",
    "content": "# StormKit\n\n> Deploy Nitro apps to StormKit.\n\n**Preset:** `stormkit`\n\n:read-more{title=\"Stormkit\" to=\"https://www.stormkit.io\"}\n\n::note\nIntegration with [Stormkit](https://www.stormkit.io/) is possible with [zero configuration](/deploy#zero-config-providers).\n::\n\n## Setup\n\nFollow the steps to [create a new app](https://app.stormkit.io/apps/new) on Stormkit.\n\n![Create a new app on Stormkit](/images/stormkit-new-app.png)\n\n## Deployment\n\nBy default, Stormkit will deploy your apps automatically when you push changes to your main branch. But to trigger a manual deploy (for example, you might do this for the very first deployment), you may click `Deploy now`.\n\n![Trigger a manual deploy with Deploy Now](/images/stormkit-deploy.png)\n"
  },
  {
    "path": "docs/2.deploy/20.providers/vercel.md",
    "content": "# Vercel\n\n> Deploy Nitro apps to Vercel.\n\n**Preset:** `vercel`\n\n:read-more{title=\"Vercel Framework Support\" to=\"https://vercel.com/docs/frameworks\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).\n::\n\n## Getting started\n\nDeploying to Vercel comes with the following features:\n- [Preview deployments](https://vercel.com/docs/deployments/environments)\n- [Fluid compute](https://vercel.com/docs/fluid-compute)\n- [Observability](https://vercel.com/docs/observability)\n- [Vercel Firewall](https://vercel.com/docs/vercel-firewall)\n\nAnd much more. Learn more in [the Vercel documentation](https://vercel.com/docs).\n\n### Deploy with Git\n\nVercel supports Nitro with zero-configuration. [Deploy Nitro to Vercel now](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fvercel%2Ftree%2Fmain%2Fexamples%2Fnitro).\n\n## API routes\n\nNitro `/api` directory isn't compatible with Vercel. Instead, you should use:\n\n- `routes/api/` for standalone usage\n\n## Bun runtime\n\n:read-more{title=\"Vercel\" to=\"https://vercel.com/docs/functions/runtimes/bun\"}\n\nYou can use [Bun](https://bun.com) instead of Node.js by specifying the runtime using the `vercel.functions` key inside `nitro.config`:\n\n```ts [nitro.config.ts]\nexport default defineNitroConfig({\n  vercel: {\n    functions: {\n      runtime: \"bun1.x\"\n    }\n  }\n})\n```\n\nAlternatively, Nitro also detects Bun automatically if you specify a `bunVersion` property in your `vercel.json`:\n\n```json [vercel.json]\n{\n  \"$schema\": \"https://openapi.vercel.sh/vercel.json\",\n  \"bunVersion\": \"1.x\"\n}\n```\n\n## Proxy route rules\n\nNitro automatically optimizes `proxy` route rules on Vercel by generating [CDN-level rewrites](https://vercel.com/docs/rewrites) at build time. This means matching requests are proxied at the edge without invoking a serverless function, reducing latency and cost.\n\n```ts [nitro.config.ts]\nexport default defineNitroConfig({\n  routeRules: {\n    // Proxied at CDN level — no function invocation\n    \"/api/**\": {\n      proxy: \"https://api.example.com/**\",\n    },\n  },\n});\n```\n\n### When CDN rewrites apply\n\nA proxy rule is offloaded to a Vercel CDN rewrite when **all** of the following are true:\n\n- The target is an **external URL** (starts with `http://` or `https://`).\n- No advanced `ProxyOptions` are set on the rule.\n\n### Fallback to runtime proxy\n\nWhen the proxy rule uses any of the following `ProxyOptions`, Nitro keeps it as a runtime proxy handled by the serverless function:\n\n- `headers` — custom headers on the outgoing request to the upstream\n- `forwardHeaders` / `filterHeaders` — header filtering\n- `fetchOptions` — custom fetch options\n- `cookieDomainRewrite` / `cookiePathRewrite` — cookie manipulation\n- `onResponse` — response callback\n\n::note\nResponse headers defined on the route rule via the `headers` option are still applied to CDN-level rewrites. Only request-level `ProxyOptions.headers` (sent to the upstream) require a runtime proxy.\n::\n\n## Scheduled tasks (Cron Jobs)\n\n:read-more{title=\"Vercel Cron Jobs\" to=\"https://vercel.com/docs/cron-jobs\"}\n\nNitro automatically converts your [`scheduledTasks`](/docs/tasks#scheduled-tasks) configuration into [Vercel Cron Jobs](https://vercel.com/docs/cron-jobs) at build time. Define your schedules in your Nitro config and deploy - no manual `vercel.json` cron configuration required.\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  experimental: {\n    tasks: true\n  },\n  scheduledTasks: {\n    // Run `cms:update` every hour\n    '0 * * * *': ['cms:update'],\n    // Run `db:cleanup` every day at midnight\n    '0 0 * * *': ['db:cleanup']\n  }\n})\n```\n\n### Secure cron job endpoints\n\n:read-more{title=\"Securing cron jobs\" to=\"https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs\"}\n\nTo prevent unauthorized access to the cron handler, set a `CRON_SECRET` environment variable in your Vercel project settings. When `CRON_SECRET` is set, Nitro validates the `Authorization` header on every cron invocation.\n\n## Custom build output configuration\n\nYou can provide additional [build output configuration](https://vercel.com/docs/build-output-api/v3) using `vercel.config` key inside `nitro.config`. It will be merged with built-in auto-generated config.\n\n## On-Demand incremental static regeneration (ISR)\n\nOn-demand revalidation allows you to purge the cache for an ISR route whenever you want, foregoing the time interval required with background revalidation.\n\nTo revalidate a page on demand:\n\n1. Create an Environment Variable which will store a revalidation secret\n    - You can use the command `openssl rand -base64 32` or [Generate a Secret](https://generate-secret.vercel.app/32) to generate a random value.\n\n2. Update your configuration:\n\n    ```ts [nitro.config.ts]\n    import { defineNitroConfig } from \"nitro/config\";\n\n    export default defineNitroConfig({\n      vercel: {\n        config: {\n          bypassToken: process.env.VERCEL_BYPASS_TOKEN\n        }\n      }\n    })\n    ```\n\n3. To trigger \"On-Demand Incremental Static Regeneration (ISR)\" and revalidate a path to a Prerender Function, make a GET or HEAD request to that path with a header of x-prerender-revalidate: `bypassToken`. When that Prerender Function endpoint is accessed with this header set, the cache will be revalidated. The next request to that function should return a fresh response.\n\n### Fine-grained ISR config via route rules\n\nBy default, query params affect cache keys but are not passed to the route handler unless specified.\n\nYou can pass an options object to `isr` route rule to configure caching behavior.\n\n- `expiration`: Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to `false` (or `isr: true` route rule) means it will never expire.\n- `group`: Group number of the asset. Prerender assets with the same group number will all be re-validated at the same time.\n- `allowQuery`: List of query string parameter names that will be cached independently.\n  - If an empty array, query values are not considered for caching.\n  - If `undefined` each unique query value is cached independently.\n  - For wildcard `/**` route rules, `url` is always added\n- `passQuery`: When `true`, the query string will be present on the `request` argument passed to the invoked function. The `allowQuery` filter still applies.\n- `exposeErrBody`: When `true`, expose the response body regardless of status code including error status codes. (default `false`\n\n```ts\nexport default defineNitroConfig({\n  routeRules: {\n    \"/products/**\": {\n      isr: {\n        allowQuery: [\"q\"],\n        passQuery: true,\n        exposeErrBody: true\n      },\n    },\n  },\n});\n```\n"
  },
  {
    "path": "docs/2.deploy/20.providers/zeabur.md",
    "content": "# Zeabur\n\n> Deploy Nitro apps to [Zeabur](https://zeabur.com).\n\n**Preset:** `zeabur`\n\n:read-more{title=\"Zeabur\" to=\"https://zeabur.com\"}\n\n::note\nIntegration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).\n::\n\n## Deploy using git\n\n1. Push your code to your git repository (Currently only GitHub supported).\n2. [Import your project](https://zeabur.com/docs/get-started) into Zeabur.\n3. Zeabur will detect that you are using Nitro and will enable the correct settings for your deployment.\n4. Your application is deployed!\n"
  },
  {
    "path": "docs/2.deploy/20.providers/zephyr.md",
    "content": "# Zephyr Cloud\n\n> Deploy Nitro apps to [Zephyr Cloud](https://zephyr-cloud.io).\n\n**Preset:** `zephyr`\n\n:read-more{title=\"Zephyr Cloud Docs\" to=\"https://docs.zephyr-cloud.io\"}\n\nZephyr support is built into Nitro through the `zephyr` preset.\n\nFor most Zephyr-specific topics such as BYOC, cloud integrations, environments, and CI/CD authentication, refer to the [Zephyr Cloud docs](https://docs.zephyr-cloud.io).\n\n::note\nZephyr is a little different from most Nitro deployment providers. Instead of targeting a single hosting vendor directly, Zephyr acts as a deployment control plane on top of either Zephyr-managed infrastructure or your own cloud integrations.\n::\n\n## BYOC model\n\nZephyr supports a BYOC (Bring Your Own Cloud) model. In Zephyr's architecture, the control plane stays managed by Zephyr, while the data plane (workers and storage) runs in your cloud accounts.\n\nThis lets you keep Zephyr's deployment workflow while using any supported Zephyr cloud integration. See the [Zephyr BYOC docs](https://docs.zephyr-cloud.io/features/byoc) for the current list of supported providers.\n\n## Deploy with Nitro CLI\n\nUse Nitro's deploy command to build and upload your app to Zephyr in one step:\n\n```bash\nnpx nitro deploy --preset zephyr\n```\n\nNitro will upload the generated output using `zephyr-agent`. If `zephyr-agent` is missing, Nitro will prompt to install it locally and will install it automatically in CI.\n\n## Deploy during build\n\nZephyr is a little different here from most Nitro providers: we recommend enabling deployment during `nitro build` and treating build as the primary deployment step.\n\nIf your CI pipeline already runs `nitro build`, enable deployment during the build step:\n\n```ts [nitro.config.ts]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  preset: \"zephyr\",\n  zephyr: {\n    deployOnBuild: true,\n  },\n});\n```\n\nThen your normal build command is enough:\n\n:pm-run{script=\"build\"}\n\nAfter the build finishes, Nitro uploads the generated output to Zephyr, deploys it to the edge, and prints the deployment URL:\n\n```txt\n◐ Building [Nitro] (preset: zephyr, compatibility: YYYY-MM-DD)\n...\nZEPHYR   Uploaded local snapshot in 110ms\nZEPHYR   Deployed to Zephyr's edge in 700ms.\nZEPHYR\nZEPHYR   https://my-app.zephyrcloud.app\n```\n\n## CI authentication\n\nZephyr requires an API token for non-interactive deployments. The example below uses the simpler personal-token style setup with `ZE_SECRET_TOKEN` together with `zephyr.deployOnBuild`.\n\n```yaml [.github/workflows/deploy.yml]\nname: Deploy with Zephyr\n\non:\n  push:\n    branches: [main]\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    env:\n      ZE_SECRET_TOKEN: ${{ secrets.ZEPHYR_AUTH_TOKEN }}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 20\n      - run: npm ci\n      - run: npm run build\n```\n\nFor more advanced CI/CD setups, Zephyr also documents organization-level server-token authentication using `ZE_SERVER_TOKEN`. See the [Zephyr CI/CD server token docs](https://docs.zephyr-cloud.io/features/ci-cd-server-token).\n\n## Options\n\n### `zephyr.deployOnBuild`\n\nDeploy to Zephyr during `nitro build` when using the `zephyr` preset.\n\n- Default: `false`\n"
  },
  {
    "path": "docs/2.deploy/20.providers/zerops.md",
    "content": "# Zerops\n\n> Deploy Nitro apps to [Zerops](https://zerops.io).\n\n**Preset:** `zerops`\n\n:read-more{title=\"zerops.io\" to=\"https://zerops.io\"}\n\n> [!IMPORTANT]\n> 🚧 This preset is currently experimental.\n\nZerops supports deploying both static and server-side rendered apps with a simple configuration file in your project root.\n\n## Starter templates\n\nIf you want to quckly get started with zerops and nitro you can use repositories [`zeropsio/recipe-nitro-nodejs`](https://github.com/zeropsio/recipe-nitro-nodejs) and [`zeropsio/recipe-nitro-static`](https://github.com/zeropsio/recipe-nitro-static) starter templates.\n\n## Project setup\n\nProjects and services can be added either through [project add wizard](https://app.zerops.io/dashboard/project-add) or imported using `zerops-project-import.yml`.\n\n::code-group\n```yml [zerops-project-import.yml (node.js)]\nproject:\n  name: nitro-app\n\nservices:\n  - hostname: app\n    type: nodejs@20\n```\n```yml [zerops-project-import.yml (static)]\nproject:\n  name: nitro-app\n\nservices:\n  - hostname: app\n    type: static\n```\n::\n\nThen create a `zerops.yml` config in your project root:\n\n::code-group\n```yml [zerops.yml (node.js)]\nzerops:\n  - setup: app\n    build:\n      base: nodejs@20\n      envVariables:\n        NITRO_PRESET: zerops\n      buildCommands:\n        - pnpm i\n        - pnpm run build\n      deployFiles:\n        - .output\n        - package.json\n        - node_modules\n    run:\n      base: nodejs@20\n      ports:\n        - port: 3000\n          httpSupport: true\n      start: node .output/server/index.mjs\n```\n```yml [zerops.yml (static)]\nzerops:\n  - setup: app\n    build:\n      base: nodejs@20\n      envVariables:\n        NITRO_PRESET: zerops-static\n      buildCommands:\n        - pnpm i\n        - pnpm build\n      deployFiles:\n        - .zerops/output/static/~\n    run:\n      base: static\n```\n::\n\nNow you can trigger the [build & deploy pipeline using the Zerops CLI](#building-deploying-your-app) or by connecting the app service with your [GitHub](https://docs.zerops.io/references/github-integration/) / [GitLab](https://docs.zerops.io/references/gitlab-integration) repository from inside the service detail.\n\n\n## Build and deploy\n\nOpen [Settings > Access Token Management](https://app.zerops.io/settings/token-management) in the Zerops app and generate a new access token.\n\nLog in using your access token with the following command:\n\n:pm-x{command=\"@zerops/zcli login <token>\"}\n\nNavigate to the root of your app (where `zerops.yml` is located) and run the following command to trigger the deploy:\n\n:pm-x{command=\"@zerops/zcli push\"}\n\nYour code can be deployed automatically on each commit or a new tag by connecting the service with your [GitHub](https://docs.zerops.io/references/gitlab-integration) / [GitLab](https://docs.zerops.io/references/gitlab-integration) repository. This connection can be set up in the service detail.\n\n\n:read-more{title=\"Zerops Documentation\" to=\"https://docs.zerops.io/\"}\n"
  },
  {
    "path": "docs/3.config/0.index.md",
    "content": "---\nicon: ri:settings-3-line\n---\n\n# Config\n\n:read-more{to=\"/guide/configuration\"}\n\n## General\n\n### `preset`\n\nUse `preset` option or `NITRO_PRESET` environment variable for custom **production** preset.\n\nPreset for development mode is always `nitro_dev` and default `node_server` for production building a standalone Node.js server.\n\nThe preset will automatically be detected when the `preset` option is not set and running in known environments.\n\n```ts\nexport default defineNitroConfig({\n  preset: \"cloudflare_pages\", // deploy to Cloudflare Pages\n});\n```\n\n### `debug`\n\n- Default: `false`{lang=ts} (`true`{lang=ts} when `DEBUG` environment variable is set)\n\nEnable debug mode for verbose logging and additional development information.\n\n```ts\nexport default defineNitroConfig({\n  debug: true,\n});\n```\n\n### `logLevel`\n\n- Default: `3`{lang=ts} (`1`{lang=ts} when the testing environment is detected)\n\nLog verbosity level. See [consola](https://github.com/unjs/consola?tab=readme-ov-file#log-level) for more information.\n\n```ts\nexport default defineNitroConfig({\n  logLevel: 4, // verbose logging\n});\n```\n\n### `runtimeConfig`\n\n- Default: `{ nitro: { ... }, ...yourOptions }`{lang=ts}\n\nServer runtime configuration.\n\n**Note:** `nitro` namespace is reserved.\n\n```ts\nexport default defineNitroConfig({\n  runtimeConfig: {\n    apiSecret: \"default-secret\", // override with NITRO_API_SECRET\n  },\n});\n```\n\n### `compatibilityDate`\n\nDeployment providers introduce new features that Nitro presets can leverage, but some of them need to be explicitly opted into.\n\nSet it to latest tested date in `YYYY-MM-DD` format to leverage latest preset features.\n\nIf this configuration is not provided, Nitro will use `\"latest\"` behavior by default.\n\n```ts\nexport default defineNitroConfig({\n  compatibilityDate: \"2025-01-01\",\n});\n```\n\n### `static`\n\n- Default: `false`{lang=ts}\n\nEnable static site generation mode.\n\n```ts\nexport default defineNitroConfig({\n  static: true, // prerender all routes\n});\n```\n\n## Features\n\n### `features`\n\n- Default: `{}`{lang=ts}\n\nEnable built-in features.\n\n#### `runtimeHooks`\n\n- Default: auto-detected (enabled if there is at least one nitro plugin)\n\nEnable runtime hooks for request and response.\n\n#### `websocket`\n\n- Default: `false`{lang=ts}\n\nEnable WebSocket support.\n\n```ts\nexport default defineNitroConfig({\n  features: {\n    runtimeHooks: true,\n    websocket: true, // enable WebSocket support\n  },\n});\n```\n\n### `experimental`\n\n- Default: `{}`\n\nEnable experimental features.\n\n#### `openAPI`\n\n- Default: `false`{lang=ts}\n\nEnable `/_scalar`, `/_swagger` and `/_openapi.json` endpoints.\n\n::note\nPrefer using the top-level [`openAPI`](#openapi) option for configuration.\n::\n\n#### `typescriptBundlerResolution`\n\nEnable TypeScript bundler module resolution. See [TypeScript#51669](https://github.com/microsoft/TypeScript/pull/51669).\n\n#### `asyncContext`\n\nEnable native async context support for `useRequest()`.\n\n#### `sourcemapMinify`\n\nSet to `false` to disable experimental sourcemap minification.\n\n#### `envExpansion`\n\nAllow env expansion in runtime config. See [#2043](https://github.com/nitrojs/nitro/pull/2043).\n\n#### `database`\n\nEnable experimental database support. See [Database](/docs/database).\n\n#### `tasks`\n\nEnable experimental tasks support. See [Tasks](/docs/tasks).\n\n```ts\nexport default defineNitroConfig({\n  experimental: {\n    typescriptBundlerResolution: true,\n    asyncContext: true,\n    envExpansion: true,\n    database: true,\n    tasks: true,\n  },\n});\n```\n\n### `openAPI`\n\nTop-level OpenAPI configuration.\n\nYou can pass an object to modify your OpenAPI specification:\n\n```js\nopenAPI: {\n  meta: {\n    title: 'My Awesome Project',\n    description: 'This might become the next big thing.',\n    version: '1.0'\n  }\n}\n```\n\nThese routes are disabled by default in production. To enable them, use the `production` key.\n`\"runtime\"` allows middleware usage, and `\"prerender\"` is the most efficient because the JSON response is constant.\n\n```js\nopenAPI: {\n    // IMPORTANT: make sure to protect OpenAPI routes if necessary!\n    production: \"runtime\", // or \"prerender\"\n}\n```\n\nIf you like to customize the Scalar integration, you can [pass a configuration object](https://github.com/scalar/scalar) like this:\n\n```js\nopenAPI: {\n  ui: {\n    scalar: {\n      theme: 'purple'\n    }\n  }\n}\n```\n\nOr if you want to customize the endpoints:\n\n```js\nopenAPI: {\n  route: \"/_docs/openapi.json\",\n  ui: {\n    scalar: {\n      route: \"/_docs/scalar\"\n    },\n    swagger: {\n      route: \"/_docs/swagger\"\n    }\n  }\n}\n```\n\n### `future`\n\n- Default: `{}`\n\nNew features pending for a major version to avoid breaking changes.\n\n#### `nativeSWR`\n\nUses built-in SWR functionality (using caching layer and storage) for Netlify and Vercel presets instead of falling back to ISR behavior.\n\n```ts\nexport default defineNitroConfig({\n  future: {\n    nativeSWR: true,\n  },\n});\n```\n\n### `storage`\n\n- Default: `{}`\n\nStorage configuration, read more in the [Storage Layer](/docs/storage) section.\n\n```ts\nexport default defineNitroConfig({\n  storage: {\n    redis: {\n      driver: \"redis\",\n      url: \"redis://localhost:6379\",\n    },\n  },\n});\n```\n\n### `devStorage`\n\n- Default: `{}`\n\nStorage configuration overrides for development mode.\n\n```ts\nexport default defineNitroConfig({\n  devStorage: {\n    redis: {\n      driver: \"fs\",\n      base: \"./data/redis\", // use filesystem in development\n    },\n  },\n});\n```\n\n### `database`\n\nDatabase connection configurations. Requires `experimental.database: true`.\n\n```ts\ndatabase: {\n  default: {\n    connector: \"sqlite\",\n    options: { name: \"db\" }\n  }\n}\n```\n\n### `devDatabase`\n\nDatabase connection configuration overrides for development mode.\n\n```ts\nexport default defineNitroConfig({\n  devDatabase: {\n    default: {\n      connector: \"sqlite\",\n      options: { name: \"db-dev\" }, // separate dev database\n    },\n  },\n});\n```\n\n### `renderer`\n\n- Type: `false`{lang=ts} | `{ handler?: string, static?: boolean, template?: string }`{lang=ts}\n\nPoints to main render entry (file should export an event handler as default).\n\n```ts\nexport default defineNitroConfig({\n  renderer: {\n    handler: \"~/renderer\", // path to the render handler\n  },\n});\n```\n\n### `serveStatic`\n\n- Type: `boolean`{lang=ts} | `'node'`{lang=ts} | `'deno'`{lang=ts} | `'inline'`{lang=ts}\n- Default: depends on the deployment preset used.\n\nServe `public/` assets in production.\n\n**Note:** It is highly recommended that your edge CDN (Nginx, Apache, Cloud) serves the `.output/public/` directory instead to enable compression and higher level caching.\n\n```ts\nexport default defineNitroConfig({\n  serveStatic: \"node\", // serve static assets using Node.js\n});\n```\n\n### `noPublicDir`\n\n- Default: `false`{lang=ts}\n\nIf enabled, disables `.output/public` directory creation. Skips copying `public/` dir and also disables pre-rendering.\n\n```ts\nexport default defineNitroConfig({\n  noPublicDir: true, // skip public directory output\n});\n```\n\n### `publicAssets`\n\nPublic asset directories to serve in development and bundle in production.\n\nIf a `public/` directory is detected, it will be added by default, but you can add more by yourself too!\n\nIt's possible to set Cache-Control headers for assets using the `maxAge` option:\n```ts\n  publicAssets: [\n    {\n      baseURL: \"images\",\n      dir: \"public/images\",\n      maxAge: 60 * 60 * 24 * 7, // 7 days\n    },\n  ],\n```\n\nThe config above generates the following header in the assets under `public/images/` folder:\n\n`cache-control: public, max-age=604800, immutable`\n\nThe `dir` option is where your files live on your file system; the `baseURL` option is the folder they will be accessible from when served/bundled.\n\n### `compressPublicAssets`\n\n- Default: `{ gzip: false, brotli: false, zstd: false }`{lang=ts}\n\nIf enabled, Nitro will generate a pre-compressed (gzip, brotli, and/or zstd) version of supported types of public assets and prerendered routes\nlarger than 1024 bytes into the public directory. Default compression levels are used. Using this option you can support zero overhead asset compression without using a CDN.\n\n```ts\nexport default defineNitroConfig({\n  compressPublicAssets: {\n    gzip: true,\n    brotli: true, // enable gzip and brotli pre-compression\n  },\n});\n```\n\n### `serverAssets`\n\nAssets can be accessed in server logic and bundled in production. [Read more](/docs/assets#server-assets).\n\n```ts\nexport default defineNitroConfig({\n  serverAssets: [\n    {\n      baseName: \"templates\",\n      dir: \"./templates\", // bundle templates/ as server assets\n    },\n  ],\n});\n```\n\n### `modules`\n\n- Default: `[]`{lang=ts}\n\nAn array of Nitro modules. Modules can be a string (path), a module object with a `setup` function, or a function.\n\n```ts\nexport default defineNitroConfig({\n  modules: [\n    \"./modules/my-module.ts\",\n    (nitro) => {\n      nitro.hooks.hook(\"compiled\", () => { /* ... */ });\n    },\n  ],\n});\n```\n\n### `plugins`\n\n- Default: `[]`\n\nAn array of paths to nitro plugins. They will be executed by order on the first initialization.\n\nNote that Nitro auto-registers the plugins in the `plugins/` directory, [learn more](/docs/plugins).\n\n```ts\nexport default defineNitroConfig({\n  plugins: [\n    \"~/plugins/my-plugin.ts\",\n  ],\n});\n```\n\n### `tasks`\n\n- Default: `{}`\n\nTask definitions. Each key is a task name with a `handler` path and optional `description`.\n\n```ts\ntasks: {\n  'db:migrate': {\n    handler: './tasks/db-migrate',\n    description: 'Run database migrations'\n  }\n}\n```\n\n### `scheduledTasks`\n\n- Default: `{}`\n\nMap of cron expressions to task name(s).\n\n```ts\nscheduledTasks: {\n  '0 * * * *': 'cleanup:temp',\n  '*/5 * * * *': ['health:check', 'metrics:collect']\n}\n```\n\n### `imports`\n\n- Default: `false`{lang=ts}\n\nAuto import options. Set to an object to enable. See [unimport](https://github.com/unjs/unimport) for more information.\n\n```ts\nexport default defineNitroConfig({\n  imports: {\n    dirs: [\"./utils\"], // auto-import from utils/ directory\n  },\n});\n```\n\n### `virtual`\n\n- Default: `{}`\n\nA map from dynamic virtual import names to their contents or an (async) function that returns it.\n\n```ts\nexport default defineNitroConfig({\n  virtual: {\n    \"#config\": `export default { version: \"1.0.0\" }`,\n  },\n});\n```\n\n### `ignore`\n\n- Default: `[]`\n\nArray of glob patterns to ignore when scanning directories.\n\n```ts\nexport default defineNitroConfig({\n  ignore: [\n    \"routes/_legacy/**\", // skip legacy route handlers\n  ],\n});\n```\n\n### `wasm`\n\n- Default: `{}`{lang=ts}\n- Type: `false`{lang=ts} | `UnwasmPluginOptions`{lang=ts}\n\nWASM support configuration. See [unwasm](https://github.com/unjs/unwasm) for options.\n\n```ts\nexport default defineNitroConfig({\n  wasm: {}, // enable WASM import support\n});\n```\n\n## Dev\n\n### `devServer`\n\n- Default: `{ watch: [] }`{lang=ts}\n\nDev server options. You can use `watch` to make the dev server reload if any file changes in specified paths.\n\nSupports `port`, `hostname`, `watch`, and `runner` options.\n\n```ts\nexport default defineNitroConfig({\n  devServer: {\n    port: 3001,\n    watch: [\"./server/plugins\"],\n  },\n});\n```\n\n### `watchOptions`\n\nWatch options for development mode. See [chokidar](https://github.com/paulmillr/chokidar) for more information.\n\n```ts\nexport default defineNitroConfig({\n  watchOptions: {\n    ignored: [\"**/node_modules/**\", \"**/dist/**\"],\n  },\n});\n```\n\n### `devProxy`\n\nProxy configuration for development server.\n\nYou can use this option to override development server routes and proxy-pass requests.\n\n```js\n{\n  devProxy: {\n    '/proxy/test': 'http://localhost:3001',\n    '/proxy/example': { target: 'https://example.com', changeOrigin: true }\n  }\n}\n```\n\nSee [httpxy](https://github.com/unjs/httpxy) for all available target options.\n\n## Logging\n\n### `logging`\n\n- Default: `{ compressedSizes: true, buildSuccess: true }`{lang=ts}\n\nControl build logging behavior. Set `compressedSizes` to `false` to skip reporting compressed bundle sizes. Set `buildSuccess` to `false` to suppress the build success message.\n\n```ts\nexport default defineNitroConfig({\n  logging: {\n    compressedSizes: false, // skip compressed size reporting\n    buildSuccess: false,\n  },\n});\n```\n\n## Routing\n\n### `baseURL`\n\nDefault: `/`{lang=ts} (or `NITRO_APP_BASE_URL` environment variable if provided)\n\nServer's main base URL.\n\n```ts\nexport default defineNitroConfig({\n  baseURL: \"/app/\", // serve app under /app/ prefix\n});\n```\n\n### `apiBaseURL`\n\n- Default: `/api`\n\nChanges the default API base URL prefix.\n\n```ts\nexport default defineNitroConfig({\n  apiBaseURL: \"/server/api\", // api routes under /server/api/\n});\n```\n\n### `handlers`\n\nServer handlers and routes.\n\nIf `routes/`, `api/` or `middleware/` directories exist inside the server directory, they will be automatically added to the handlers array.\n\n```ts\nexport default defineNitroConfig({\n  handlers: [\n    { route: \"/health\", handler: \"./handlers/health.ts\" },\n    { route: \"/admin/**\", handler: \"./handlers/admin.ts\", method: \"get\" },\n  ],\n});\n```\n\n### `devHandlers`\n\nRegular handlers refer to the path of handlers to be imported and transformed by the bundler.\n\nThere are situations in that we directly want to provide a handler instance with programmatic usage.\n\nWe can use `devHandlers` but note that they are **only available in development mode** and **not in production build**.\n\n```ts\nexport default defineNitroConfig({\n  devHandlers: [\n    { route: \"/__dev\", handler: eventHandler(() => \"dev-only route\") },\n  ],\n});\n```\n\n### `routes`\n\n- Default: `{}`{lang=ts}\n\nInline route definitions. A map from route pattern to handler path or handler options.\n\n```ts\nexport default defineNitroConfig({\n  routes: {\n    \"/hello\": \"./routes/hello.ts\",\n    \"/greet\": { handler: \"./routes/greet.ts\", method: \"post\" },\n  },\n});\n```\n\n### `errorHandler`\n\n- Type: `string`{lang=ts} | `string[]`{lang=ts}\n\nPath(s) to custom runtime error handler(s). Replaces nitro's built-in error page.\n\n**Example:**\n\n```js [nitro.config]\nimport { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  errorHandler: \"~/error\",\n});\n```\n\n```js [error.ts]\nexport default defineNitroErrorHandler((error, event) => {\n  return new Response('[custom error handler] ' + error.stack, {\n    headers: { 'Content-Type': 'text/plain' }\n  });\n});\n```\n\n### `routeRules`\n\n**🧪 Experimental!**\n\nRoute options. It is a map from route pattern (following [rou3](https://github.com/h3js/rou3)) to route options.\n\nWhen `cache` option is set, handlers matching pattern will be automatically wrapped with `defineCachedEventHandler`.\n\nSee the [Cache API](/docs/cache) for all available cache options.\n\n::note\n`swr: true|number` is shortcut for `cache: { swr: true, maxAge: number }`\n::\n\n**Example:**\n\n```js\nrouteRules: {\n  '/blog/**': { swr: true },\n  '/blog/**': { swr: 600 },\n  '/blog/**': { static: true },\n  '/blog/**': { cache: { /* cache options*/ } },\n  '/assets/**': { headers: { 'cache-control': 's-maxage=0' } },\n  '/api/v1/**': { cors: true, headers: { 'access-control-allow-methods': 'GET' } },\n  '/old-page': { redirect: '/new-page' }, // uses status code 307 (Temporary Redirect)\n  '/old-page2': { redirect: { to:'/new-page2', statusCode: 301 } },\n  '/old-page/**': { redirect: '/new-page/**' },\n  '/proxy/example': { proxy: 'https://example.com' },\n  '/proxy/**': { proxy: '/api/**' },\n  '/admin/**': { basicAuth: { username: 'admin', password: 'secret' } },\n}\n```\n\n### `prerender`\n\nDefault:\n\n```ts\n{\n  autoSubfolderIndex: true,\n  concurrency: 1,\n  interval: 0,\n  failOnError: false,\n  crawlLinks: false,\n  ignore: [],\n  routes: [],\n  retry: 3,\n  retryDelay: 500\n}\n```\n\nPrerendered options. Any route specified will be fetched during the build and copied to the `.output/public` directory as a static asset.\n\nAny route (string) that starts with a prefix listed in `ignore` or matches a regular expression or function will be ignored.\n\nIf `crawlLinks` option is set to `true`, nitro starts with `/` by default (or all routes in `routes` array) and for HTML pages extracts `<a>` tags and prerender them as well.\n\nYou can set `failOnError` option to `true` to stop the CI when Nitro could not prerender a route.\n\nThe `interval` and `concurrency` options lets you control the speed of pre-rendering, can be useful to avoid hitting some rate-limit if you call external APIs.\n\nSet `autoSubfolderIndex` lets you control how to generate the files in the `.output/public` directory:\n\n```bash\n# autoSubfolderIndex: true (default)\n/about -> .output/public/about/index.html\n# autoSubfolderIndex: false\n/about -> .output/public/about.html\n```\n\nThis option is useful when your hosting provider does not give you an option regarding the trailing slash.\n\nThe prerenderer will attempt to render pages 3 times with a delay of 500ms. Use `retry` and `retryDelay` to change this behavior.\n\n## Directories\n\n### `workspaceDir`\n\nProject workspace root directory.\n\nThe workspace (e.g. pnpm workspace)  directory is automatically detected when the `workspaceDir` option is not set.\n\n```ts\nexport default defineNitroConfig({\n  workspaceDir: \"../\", // monorepo root\n});\n```\n\n### `rootDir`\n\nProject main directory.\n\n```ts\nexport default defineNitroConfig({\n  rootDir: \"./src/server\",\n});\n```\n\n### `serverDir`\n\n- Default: `false`{lang=ts}\n- Type: `boolean`{lang=ts} | `\"./\"` | `\"./server\"` | `string`{lang=ts}\n\nServer directory for scanning `api/`, `routes/`, `plugins/`, `utils/`, `middleware/`, `assets/`, and `tasks/` folders.\n\nWhen set to `false`, automatic directory scanning is disabled. Set to `\"./\"` to use the root directory, or `\"./server\"` to use a `server/` subdirectory.\n\n```ts\nexport default defineNitroConfig({\n  serverDir: \"./server\", // scan server/ subdirectory\n});\n```\n\n### `scanDirs`\n\n- Default: (source directory when empty array)\n\nList of directories to scan and auto-register files, such as API routes.\n\n```ts\nexport default defineNitroConfig({\n  scanDirs: [\"./modules/auth/api\", \"./modules/billing/api\"],\n});\n```\n\n### `apiDir`\n\n- Default: `api`\n\nDefines a different directory to scan for api route handlers.\n\n```ts\nexport default defineNitroConfig({\n  apiDir: \"endpoints\", // scan endpoints/ instead of api/\n});\n```\n\n### `routesDir`\n\n- Default: `routes`\n\nDefines a different directory to scan for route handlers.\n\n```ts\nexport default defineNitroConfig({\n  routesDir: \"pages\", // scan pages/ instead of routes/\n});\n```\n\n### `buildDir`\n\n- Default: `node_modules/.nitro`\n\nNitro's temporary working directory for generating build-related files.\n\n```ts\nexport default defineNitroConfig({\n  buildDir: \".nitro\", // use .nitro/ in project root\n});\n```\n\n### `output`\n\n- Default: `{ dir: '.output', serverDir: '.output/server', publicDir: '.output/public' }`\n\nOutput directories for production bundle.\n\n```ts\nexport default defineNitroConfig({\n  output: {\n    dir: \"dist\",\n    serverDir: \"dist/server\",\n    publicDir: \"dist/public\",\n  },\n});\n```\n\n## Build\n\n### `builder`\n\n- Type: `\"rollup\"`{lang=ts} | `\"rolldown\"`{lang=ts} | `\"vite\"`{lang=ts}\n- Default: `undefined`{lang=ts} (auto-detected)\n\nSpecify the bundler to use for building.\n\n```ts\nexport default defineNitroConfig({\n  builder: \"vite\",\n});\n```\n\n### `rollupConfig`\n\nAdditional rollup configuration.\n\n```ts\nexport default defineNitroConfig({\n  rollupConfig: {\n    output: { manualChunks: { vendor: [\"lodash-es\"] } },\n  },\n});\n```\n\n### `rolldownConfig`\n\nAdditional rolldown configuration.\n\n```ts\nexport default defineNitroConfig({\n  rolldownConfig: {\n    output: { banner: \"/* built with nitro */\" },\n  },\n});\n```\n\n### `entry`\n\nBundler entry point.\n\n```ts\nexport default defineNitroConfig({\n  entry: \"./server/entry.ts\", // custom entry file\n});\n```\n\n### `unenv`\n\n[unenv](https://github.com/unjs/unenv/) preset(s) for environment compatibility.\n\n```ts\nexport default defineNitroConfig({\n  unenv: {\n    alias: { \"my-module\": \"my-module/web\" },\n  },\n});\n```\n\n### `alias`\n\nPath aliases for module resolution.\n\n```ts\nexport default defineNitroConfig({\n  alias: {\n    \"~utils\": \"./src/utils\",\n    \"#shared\": \"./shared\",\n  },\n});\n```\n\n### `minify`\n\n- Default: `false`\n\nMinify bundle.\n\n```ts\nexport default defineNitroConfig({\n  minify: true, // minify production bundle\n});\n```\n\n### `inlineDynamicImports`\n\n- Default: `false`\n\nBundle all code into a single file instead of creating separate chunks per route.\n\nWhen `false`, each route handler becomes a separate chunk loaded on-demand. When `true`, everything is bundled together. Some presets enable this by default.\n\n```ts\nexport default defineNitroConfig({\n  inlineDynamicImports: true, // single output file\n});\n```\n\n### `sourcemap`\n\n- Default: `false`{lang=ts}\n\nEnable source map generation. See [options](https://rollupjs.org/configuration-options/#output-sourcemap).\n\n```ts\nexport default defineNitroConfig({\n  sourcemap: true, // generate .map files\n});\n```\n\n### `node`\n\n- Default: `true`{lang=ts}\n\nSpecify whether the build is used for Node.js or not. If set to `false`, nitro tries to mock Node.js dependencies using [unenv](https://github.com/unjs/unenv) and adjust its behavior.\n\n```ts\nexport default defineNitroConfig({\n  node: false, // target non-Node.js runtimes\n});\n```\n\n### `moduleSideEffects`\n\nDefault: `['unenv/polyfill/']`\n\nSpecifies module imports that have side-effects.\n\n```ts\nexport default defineNitroConfig({\n  moduleSideEffects: [\"unenv/polyfill/\", \"reflect-metadata\"],\n});\n```\n\n### `replace`\n\nBuild-time string replacements.\n\n```ts\nexport default defineNitroConfig({\n  replace: {\n    \"process.env.APP_VERSION\": JSON.stringify(\"1.0.0\"),\n  },\n});\n```\n\n### `commonJS`\n\nSpecifies additional configuration for the rollup CommonJS plugin.\n\n```ts\nexport default defineNitroConfig({\n  commonJS: {\n    requireReturnsDefault: \"auto\",\n  },\n});\n```\n\n### `exportConditions`\n\nCustom export conditions for module resolution.\n\n```ts\nexport default defineNitroConfig({\n  exportConditions: [\"worker\", \"production\"],\n});\n```\n\n### `noExternals`\n\n- Default: `false`{lang=ts}\n\nPrevent specific packages from being externalized. Set to `true` to bundle all dependencies, or pass an array of package names/patterns.\n\n```ts\nexport default defineNitroConfig({\n  noExternals: true, // bundle all dependencies\n});\n```\n\n### `traceDeps`\n\n- Default: `[]`{lang=ts}\n\nAdditional dependencies to trace and include in the build output.\n\n```ts\nexport default defineNitroConfig({\n  traceDeps: [\"sharp\", \"better-sqlite3\"],\n});\n```\n\n### `oxc`\n\nOXC options for rolldown builds. Includes `minify` and `transform` sub-options.\n\n```ts\nexport default defineNitroConfig({\n  oxc: {\n    minify: { compress: true, mangle: true },\n  },\n});\n```\n\n## Advanced\n\n### `dev`\n\n- Default: `true` for development and `false` for production.\n\n**⚠️ Caution! This is an advanced configuration. Things can go wrong if misconfigured.**\n\n```ts\nexport default defineNitroConfig({\n  dev: true, // force development mode behavior\n});\n```\n\n### `typescript`\n\nDefault: `{ strict: true, generateRuntimeConfigTypes: false, generateTsConfig: false }`{lang=ts}\n\nTypeScript configuration options including `strict`, `generateRuntimeConfigTypes`, `generateTsConfig`, `tsConfig`, `generatedTypesDir`, and `tsconfigPath`.\n\n```ts\nexport default defineNitroConfig({\n  typescript: {\n    strict: true,\n    generateTsConfig: true,\n  },\n});\n```\n\n### `hooks`\n\n**⚠️ Caution! This is an advanced configuration. Things can go wrong if misconfigured.**\n\nnitro hooks. See [hookable](https://github.com/unjs/hookable) for more information.\n\n```ts\nexport default defineNitroConfig({\n  hooks: {\n    compiled(nitro) {\n      console.log(\"Build compiled successfully!\");\n    },\n  },\n});\n```\n\n### `commands`\n\n**⚠️ Caution! This is an advanced configuration. Things can go wrong if misconfigured.**\n\nPreview and deploy command hints are usually filled by deployment presets.\n\n```ts\nexport default defineNitroConfig({\n  commands: {\n    preview: \"node ./server/index.mjs\",\n  },\n});\n```\n\n### `devErrorHandler`\n\n**⚠️ Caution! This is an advanced configuration. Things can go wrong if misconfigured.**\n\nA custom error handler function for development errors.\n\n```ts\nexport default defineNitroConfig({\n  devErrorHandler: (error, event) => {\n    return new Response(`Dev error: ${error.message}`, { status: 500 });\n  },\n});\n```\n\n### `framework`\n\n- Default: `{ name: \"nitro\", version: \"<current>\" }`{lang=ts}\n\nFramework information. Used by presets and build info. Typically set by higher-level frameworks (e.g. Nuxt).\n\n```ts\nexport default defineNitroConfig({\n  framework: { name: \"my-framework\", version: \"2.0.0\" },\n});\n```\n\n## Preset options\n\n### `firebase`\n\nThe options for the firebase functions preset. See [Preset Docs](/deploy/providers/firebase#options)\n\n```ts\nexport default defineNitroConfig({\n  firebase: {\n    gen: 2, // use Cloud Functions 2nd gen\n    region: \"us-central1\",\n  },\n});\n```\n\n### `vercel`\n\nThe options for the vercel preset. See [Preset Docs](/deploy/providers/vercel)\n\n```ts\nexport default defineNitroConfig({\n  vercel: {\n    config: { runtime: \"nodejs20.x\" },\n  },\n});\n```\n\n### `cloudflare`\n\nThe options for the cloudflare preset. See [Preset Docs](/deploy/providers/cloudflare)\n\n```ts\nexport default defineNitroConfig({\n  cloudflare: {\n    wrangler: { compatibility_date: \"2025-01-01\" },\n  },\n});\n```\n\n### `zephyr`\n\nThe options for the zephyr preset. See [Preset Docs](/deploy/providers/zephyr#options)\n"
  },
  {
    "path": "docs/4.examples/0.index.md",
    "content": "---\nicon: i-lucide-folder-code\n---\n\n# Examples\n\n> Explore Nitro examples to learn how to build full-stack applications\n"
  },
  {
    "path": "docs/4.examples/api-routes.md",
    "content": "---\ncategory: features\nicon: i-lucide-route\n---\n\n# API Routes\n\n> File-based API routing with HTTP method support and dynamic parameters.\n\n<!-- automd:ui-code-tree src=\"../../examples/api-routes\" default=\"api/hello.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"api/hello.ts\" expandAll}\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <title>API Routes</title>\n  </head>\n  <body>\n    <h2>API Routes:</h2>\n    <ul>\n      <li><a href=\"/api/hello\">/api/hello</a></li>\n      <li><a href=\"/api/hello/world\">/api/hello/world</a></li>\n      <li><a href=\"/api/test\">/api/test</a></li>\n    </ul>\n  </body>\n</html>\n```\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n```\n\n```ts [api/test.get.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Test get handler\");\n```\n\n```ts [api/test.post.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const body = await event.req.json();\n  return {\n    message: \"Test post handler\",\n    body,\n  };\n});\n```\n\n```ts [api/hello/[name].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => `Hello (param: ${event.context.params!.name})!`);\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/api-routes/README.md\" -->\n\nNitro supports file-based routing in the `api/` or `routes/` directory. Each file becomes an API endpoint based on its path.\n\n## Basic Route\n\nCreate a file in the `api/` directory to define a route. The file path becomes the URL path:\n\n```ts [api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n```\n\nThis creates a `GET /api/hello` endpoint.\n\n## Dynamic Routes\n\nUse square brackets `[param]` for dynamic URL segments. Access params via `event.context.params`:\n\n```ts [api/hello/[name].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => `Hello (param: ${event.context.params!.name})!`);\n```\n\nThis creates a `GET /api/hello/:name` endpoint (e.g., `/api/hello/world`).\n\n## HTTP Methods\n\nSuffix your file with the HTTP method (`.get.ts`, `.post.ts`, `.put.ts`, `.delete.ts`, etc.):\n\n### GET Handler\n\n```ts [api/test.get.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Test get handler\");\n```\n\n### POST Handler\n\n```ts [api/test.post.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const body = await event.req.json();\n  return {\n    message: \"Test post handler\",\n    body,\n  };\n});\n```\n\n<!-- /automd -->\n\n## Learn More\n\n- [Routing](/docs/routing)\n"
  },
  {
    "path": "docs/4.examples/auto-imports.md",
    "content": "---\ncategory: config\nicon: i-lucide-import\n---\n\n# Auto Imports\n\n> Automatic imports for utilities and composables.\n\n<!-- automd:ui-code-tree src=\"../../examples/auto-imports\" default=\"nitro.config.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"nitro.config.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n  imports: {},\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { makeGreeting } from \"./server/utils/hello.ts\";\n\nexport default defineHandler(() => `<h1>${makeGreeting(\"Nitro\")}</h1>`);\n```\n\n```json [tsconfig.json]\n{\n  \"include\": [\".nitro/types/nitro-imports.d.ts\", \"src\"]\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [server/utils/hello.ts]\nexport function makeGreeting(name: string) {\n  return `Hello, ${name}!`;\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/auto-imports/README.md\" -->\n\nFunctions exported from `server/utils/` are automatically available without explicit imports when auto-imports are enabled. Define a utility once and use it anywhere in your server code.\n\n## Configuration\n\nEnable auto-imports by setting `imports` in your config:\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n  imports: {},\n});\n```\n\n## Using Auto Imports\n\n1. Create a utility file in `server/utils/`:\n\n```ts [server/utils/hello.ts]\nexport function makeGreeting(name: string) {\n  return `Hello, ${name}!`;\n}\n```\n\n2. The function is available without importing it:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { makeGreeting } from \"./server/utils/hello.ts\";\n\nexport default defineHandler(() => `<h1>${makeGreeting(\"Nitro\")}</h1>`);\n```\n\nWith this setup, any function exported from `server/utils/` becomes globally available. Nitro scans the directory and generates the necessary imports automatically.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Configuration](/docs/configuration)\n"
  },
  {
    "path": "docs/4.examples/cached-handler.md",
    "content": "---\ncategory: features\nicon: i-lucide-clock\n---\n\n# Cached Handler\n\n> Cache route responses with configurable bypass logic.\n\n<!-- automd:ui-code-tree src=\"../../examples/cached-handler\" default=\"server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { html } from \"nitro\";\nimport { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler(\n  async () => {\n    await new Promise((resolve) => setTimeout(resolve, 500));\n    return html`\n      Response generated at ${new Date().toISOString()} (took 500ms)\n      <br />(<a href=\"?skipCache=true\">skip cache</a>)\n    `;\n  },\n  { shouldBypassCache: ({ req }) => req.url.includes(\"skipCache=true\") }\n);\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/cached-handler/README.md\" -->\n\nThis example shows how to cache an expensive operation (a 500 ms delay) and conditionally bypass the cache using a query parameter. On first request, the handler executes and caches the result. Subsequent requests return the cached response instantly until the cache expires or is bypassed.\n\n## How It Works\n\n```ts [server.ts]\nimport { html } from \"nitro\";\nimport { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler(\n  async () => {\n    await new Promise((resolve) => setTimeout(resolve, 500));\n    return html`\n      Response generated at ${new Date().toISOString()} (took 500ms)\n      <br />(<a href=\"?skipCache=true\">skip cache</a>)\n    `;\n  },\n  { shouldBypassCache: ({ req }) => req.url.includes(\"skipCache=true\") }\n);\n```\n\nThe handler simulates a slow operation with a 500ms delay. As `defineCachedHandler` wraps it, the response is cached after the first execution. The `shouldBypassCache` option checks for `?skipCache=true` in the URL and when present the cache is skipped and the handler runs fresh.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Cache](/docs/cache)\n- [Storage](/docs/storage)\n"
  },
  {
    "path": "docs/4.examples/custom-error-handler.md",
    "content": "---\ncategory: features\nicon: i-lucide-alert-circle\n---\n\n# Custom Error Handler\n\n> Customize error responses with a global error handler.\n\n<!-- automd:ui-code-tree src=\"../../examples/custom-error-handler\" default=\"error.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"error.ts\" expandAll}\n\n```ts [error.ts]\nimport { defineErrorHandler } from \"nitro\";\n\nexport default defineErrorHandler((error, _event) => {\n  return new Response(`Custom Error Handler: ${error.message}`, {\n    status: 500,\n    headers: { \"Content-Type\": \"text/plain\" },\n  });\n});\n```\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n// import errorHandler from \"./error\";\n\nexport default defineConfig({\n  errorHandler: \"./error.ts\",\n  // devErrorHandler: errorHandler,\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { defineHandler, HTTPError } from \"nitro\";\n\nexport default defineHandler(() => {\n  throw new HTTPError(\"Example Error!\", { status: 500 });\n});\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/custom-error-handler/README.md\" -->\n\nThis example shows how to intercept all errors and return a custom response format. When any route throws an error, Nitro calls your error handler instead of returning the default error page.\n\n## Error Handler\n\nCreate an `error.ts` file in your project root to define the global error handler:\n\n```ts [error.ts]\nimport { defineErrorHandler } from \"nitro\";\n\nexport default defineErrorHandler((error, _event) => {\n  return new Response(`Custom Error Handler: ${error.message}`, {\n    status: 500,\n    headers: { \"Content-Type\": \"text/plain\" },\n  });\n});\n```\n\nThe handler receives the thrown error and the H3 event object. You can use the event to access request details like headers, cookies, or the URL path to customize responses per route.\n\n## Triggering an Error\n\nThe main handler throws an error to demonstrate the custom error handler:\n\n```ts [server.ts]\nimport { defineHandler, HTTPError } from \"nitro\";\n\nexport default defineHandler(() => {\n  throw new HTTPError(\"Example Error!\", { status: 500 });\n});\n```\n\nWhen you visit the page, instead of seeing a generic error page, you'll see \"Custom Error Handler: Example Error!\" because the error handler intercepts the thrown error.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/database.md",
    "content": "---\ncategory: features\nicon: i-lucide-database\n---\n\n# Database\n\n> Built-in database support with SQL template literals.\n\n<!-- automd:ui-code-tree src=\"../../examples/database\" default=\"server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  experimental: {\n    database: true,\n    tasks: true,\n  },\n  database: {\n    default: { connector: \"sqlite\" },\n  },\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineHandler(async () => {\n  const db = useDatabase();\n\n  // Create users table\n  await db.sql`DROP TABLE IF EXISTS users`;\n  await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n  // Add a new user\n  const userId = String(Math.round(Math.random() * 10_000));\n  await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;\n\n  // Query for users\n  const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\n\n  return {\n    rows,\n  };\n});\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [tasks/db/migrate.ts]\nimport { defineTask } from \"nitro/task\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineTask({\n  meta: {\n    description: \"Run database migrations\",\n  },\n  async run() {\n    const db = useDatabase();\n\n    console.log(\"Running database migrations...\");\n\n    // Create users table\n    await db.sql`DROP TABLE IF EXISTS users`;\n    await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n    return {\n      result: \"Database migrations complete!\",\n    };\n  },\n});\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/database/README.md\" -->\n\nNitro provides a built-in database layer that uses SQL template literals for safe, parameterized queries. This example creates a users table, inserts a record, and queries it back.\n\n## Querying the Database\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineHandler(async () => {\n  const db = useDatabase();\n\n  // Create users table\n  await db.sql`DROP TABLE IF EXISTS users`;\n  await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n  // Add a new user\n  const userId = String(Math.round(Math.random() * 10_000));\n  await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;\n\n  // Query for users\n  const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\n\n  return {\n    rows,\n  };\n});\n```\n\nRetrieve the database instance using `useDatabase()`. The database can be queried using `db.sql`, and variables like `${userId}` are automatically escaped to prevent SQL injection.\n\n## Running Migrations with Tasks\n\nNitro tasks let you run operations outside of request handlers. For database migrations, create a task file in `tasks/` and run it via the CLI. This keeps schema changes separate from your application code.\n\n```ts [tasks/db/migrate.ts]\nimport { defineTask } from \"nitro/task\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineTask({\n  meta: {\n    description: \"Run database migrations\",\n  },\n  async run() {\n    const db = useDatabase();\n\n    console.log(\"Running database migrations...\");\n\n    // Create users table\n    await db.sql`DROP TABLE IF EXISTS users`;\n    await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n    return {\n      result: \"Database migrations complete!\",\n    };\n  },\n});\n```\n\n<!-- /automd -->\n\n## Learn More\n\n- [Database](/docs/database)\n- [Tasks](/docs/tasks)\n"
  },
  {
    "path": "docs/4.examples/elysia.md",
    "content": "---\ncategory: backend frameworks\nicon: i-skill-icons-elysia-dark\n---\n\n# Elysia\n\n> Integrate Elysia with Nitro using the server entry.\n\n<!-- automd:ui-code-tree src=\"../../examples/elysia\" default=\"server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"elysia\": \"^1.4.28\",\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { Elysia } from \"elysia\";\n\nconst app = new Elysia();\n\napp.get(\"/\", () => \"Hello, Elysia with Nitro!\");\n\nexport default app.compile();\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/elysia/README.md\" -->\n\n## Server Entry\n\n```ts [server.ts]\nimport { Elysia } from \"elysia\";\n\nconst app = new Elysia();\n\napp.get(\"/\", () => \"Hello, Elysia with Nitro!\");\n\nexport default app.compile();\n```\n\nNitro auto-detects `server.ts` in your project root and uses it as the server entry. The Elysia app handles all incoming requests, giving you full control over routing and middleware.\n\nCall `app.compile()` before exporting to optimize the router for production.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Server Entry](/docs/server-entry)\n- [Elysia Documentation](https://elysiajs.com/)\n"
  },
  {
    "path": "docs/4.examples/express.md",
    "content": "---\ncategory: backend frameworks\nicon: i-simple-icons-express\n---\n\n# Express\n\n> Integrate Express with Nitro using the server entry.\n\n<!-- automd:ui-code-tree src=\"../../examples/express\" default=\"server.node.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.node.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^5.0.6\",\n    \"express\": \"^5.2.1\",\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.node.ts]\nimport Express from \"express\";\n\nconst app = Express();\n\napp.use(\"/\", (_req, res) => {\n  res.send(\"Hello from Express with Nitro!\");\n});\n\nexport default app;\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/express/README.md\" -->\n\n## Server Entry\n\n```ts [server.node.ts]\nimport Express from \"express\";\n\nconst app = Express();\n\napp.use(\"/\", (_req, res) => {\n  res.send(\"Hello from Express with Nitro!\");\n});\n\nexport default app;\n```\n\nNitro auto-detects `server.node.ts` in your project root and uses it as the server entry. The Express app handles all incoming requests, giving you full control over routing and middleware.\n\n::note\nThe `.node.ts` suffix indicates this entry is Node.js specific and won't work in other runtimes like Cloudflare Workers or Deno.\n::\n\n<!-- /automd -->\n\n## Learn More\n\n- [Server Entry](/docs/server-entry)\n- [Express Documentation](https://expressjs.com/)\n"
  },
  {
    "path": "docs/4.examples/fastify.md",
    "content": "---\ncategory: backend frameworks\nicon: i-simple-icons-fastify\n---\n\n# Fastify\n\n> Integrate Fastify with Nitro using the server entry.\n\n<!-- automd:ui-code-tree src=\"../../examples/fastify\" default=\"server.node.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.node.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"fastify\": \"^5.8.2\",\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.node.ts]\nimport Fastify from \"fastify\";\n\nconst app = Fastify();\n\napp.get(\"/\", () => \"Hello, Fastify with Nitro!\");\n\nawait app.ready();\n\nexport default app.routing;\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/fastify/README.md\" -->\n\n## Server Entry\n\n```ts [server.node.ts]\nimport Fastify from \"fastify\";\n\nconst app = Fastify();\n\napp.get(\"/\", () => \"Hello, Fastify with Nitro!\");\n\nawait app.ready();\n\nexport default app.routing;\n```\n\nNitro auto-detects `server.node.ts` in your project root and uses it as the server entry.\n\nCall `await app.ready()` to initialize all registered plugins before exporting. Export `app.routing` (not `app`) to provide Nitro with the request handler function.\n\n::note\nThe `.node.ts` suffix indicates this entry is Node.js specific and won't work in other runtimes like Cloudflare Workers or Deno.\n::\n\n<!-- /automd -->\n\n## Learn More\n\n- [Server Entry](/docs/server-entry)\n- [Fastify Documentation](https://fastify.dev/)\n"
  },
  {
    "path": "docs/4.examples/hello-world.md",
    "content": "---\ncategory: features\nicon: i-lucide-sparkles\n---\n\n# Hello World\n\n> Minimal Nitro server using the web standard fetch handler.\n\n<!-- automd:ui-code-tree src=\"../../examples/hello-world\" default=\"server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\",\n    \"preview\": \"node .output/server/index.mjs\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nexport default {\n  fetch(req: Request) {\n    return new Response(\"Nitro Works!\");\n  },\n};\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/hello-world/README.md\" -->\n\nThe simplest Nitro server. Export an object with a `fetch` method that receives a standard `Request` and returns a `Response`. No frameworks, no abstractions, just the web platform.\n\n\n## Server Entry\n\n```ts [server.ts]\nexport default {\n  fetch(req: Request) {\n    return new Response(\"Nitro Works!\");\n  },\n};\n```\n\nThe `fetch` method follows the same signature as Service Workers and Cloudflare Workers. This pattern works across all deployment targets because it uses web standards.\n\nAdd the Nitro plugin to Vite and it handles the rest: dev server, hot reloading, and production builds.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Server Entry](/docs/server-entry)\n- [Configuration](/docs/configuration)\n"
  },
  {
    "path": "docs/4.examples/hono.md",
    "content": "---\ncategory: backend frameworks\nicon: i-logos-hono\n---\n\n# Hono\n\n> Integrate Hono with Nitro using the server entry.\n\n<!-- automd:ui-code-tree src=\"../../examples/hono\" default=\"server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"hono\": \"^4.12.8\",\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { Hono } from \"hono\";\n\nconst app = new Hono();\n\napp.get(\"/\", (c) => {\n  return c.text(\"Hello, Hono with Nitro!\");\n});\n\nexport default app;\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/hono/README.md\" -->\n\n## Server Entry\n\n```ts [server.ts]\nimport { Hono } from \"hono\";\n\nconst app = new Hono();\n\napp.get(\"/\", (c) => {\n  return c.text(\"Hello, Hono with Nitro!\");\n});\n\nexport default app;\n```\n\nNitro auto-detects `server.ts` in your project root and uses it as the server entry. The Hono app handles all incoming requests, giving you full control over routing and middleware.\n\nHono is cross-runtime compatible, so this server entry works across all Nitro deployment targets including Node.js, Deno, Bun, and Cloudflare Workers.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Server Entry](/docs/server-entry)\n- [Hono Documentation](https://hono.dev/)\n"
  },
  {
    "path": "docs/4.examples/import-alias.md",
    "content": "---\ncategory: config\nicon: i-lucide-at-sign\n---\n\n# Import Alias\n\n> Custom import aliases for cleaner module paths.\n\n<!-- automd:ui-code-tree src=\"../../examples/import-alias\" default=\"server/routes/index.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server/routes/index.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"imports\": {\n    \"#server/*\": \"./server/*\"\n  },\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\",\n    \"preview\": \"node .output/server/index.mjs\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"paths\": {\n      \"~server/*\": [\"./server/*\"]\n    }\n  }\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()], resolve: { tsconfigPaths: true } });\n```\n\n```ts [server/routes/index.ts]\nimport { sum } from \"~server/utils/math.ts\";\n\nimport { rand } from \"#server/utils/math.ts\";\n\nexport default () => {\n  const [a, b] = [rand(1, 10), rand(1, 10)];\n  const result = sum(a, b);\n  return `The sum of ${a} + ${b} = ${result}`;\n};\n```\n\n```ts [server/utils/math.ts]\nexport function rand(min: number, max: number): number {\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nexport function sum(a: number, b: number): number {\n  return a + b;\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/import-alias/README.md\" -->\n\nImport aliases like `~` and `#` let you reference modules with shorter paths instead of relative imports.\n\n## Importing Using Aliases\n\n```ts [server/routes/index.ts]\nimport { sum } from \"~server/utils/math.ts\";\n\nimport { rand } from \"#server/utils/math.ts\";\n\nexport default () => {\n  const [a, b] = [rand(1, 10), rand(1, 10)];\n  const result = sum(a, b);\n  return `The sum of ${a} + ${b} = ${result}`;\n};\n```\n\nThe route imports the `sum` function using `~server/` and `rand` using `#server/`. Both resolve to the same `server/utils/math.ts` file. The handler generates two random numbers and returns their sum.\n\n## Configuration\n\nAliases can be configured in `package.json` imports field or `nitro.config.ts`.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Configuration](/docs/configuration)\n"
  },
  {
    "path": "docs/4.examples/middleware.md",
    "content": "---\ncategory: features\nicon: i-lucide-layers\n---\n\n# Middleware\n\n> Request middleware for authentication, logging, and request modification.\n\n<!-- automd:ui-code-tree src=\"../../examples/middleware\" default=\"server/middleware/auth.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server/middleware/auth.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => ({\n  auth: event.context.auth,\n}));\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [server/middleware/auth.ts]\nimport { defineMiddleware } from \"nitro\";\n\nexport default defineMiddleware((event) => {\n  event.context.auth = { name: \"User \" + Math.round(Math.random() * 100) };\n});\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/middleware/README.md\" -->\n\nMiddleware functions run before route handlers on every request. They can modify the request, add context, or return early responses.\n\n## Defining Middleware\n\nCreate files in `server/middleware/`. They run in alphabetical order:\n\n```ts [server/middleware/auth.ts]\nimport { defineMiddleware } from \"nitro\";\n\nexport default defineMiddleware((event) => {\n  event.context.auth = { name: \"User \" + Math.round(Math.random() * 100) };\n});\n```\n\nMiddleware can:\n- Add data to `event.context` for use in handlers\n- Return a response early to short-circuit the request\n- Modify request headers or other properties\n\n## Accessing Context in Handlers\n\nData added to `event.context` in middleware is available in all subsequent handlers:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => ({\n  auth: event.context.auth,\n}));\n```\n\n<!-- /automd -->\n\n## Learn More\n\n- [Routing](/docs/routing)\n"
  },
  {
    "path": "docs/4.examples/mono-jsx.md",
    "content": "---\ncategory: server side rendering\nicon: i-lucide-brackets\n---\n\n# Mono JSX\n\n> Server-side JSX rendering in Nitro with mono-jsx.\n\n<!-- automd:ui-code-tree src=\"../../examples/mono-jsx\" default=\"server.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.tsx\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"mono-jsx\": \"latest\",\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```tsx [server.tsx]\nexport default () => (\n  <html>\n    <h1>Nitro + mono-jsx works!</h1>\n  </html>\n);\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"mono-jsx\"\n  }\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/mono-jsx/README.md\" -->\n\n## Server Entry\n\n```tsx [server.tsx]\nexport default () => (\n  <html>\n    <h1>Nitro + mono-jsx works!</h1>\n  </html>\n);\n```\n\nNitro auto-detects `server.tsx` and uses mono-jsx to transform JSX into HTML. Export a function that returns JSX, and Nitro sends the rendered HTML as the response.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Renderer](/docs/renderer)\n- [mono-jsx](https://github.com/aspect-dev/mono-jsx)\n"
  },
  {
    "path": "docs/4.examples/nano-jsx.md",
    "content": "---\ncategory: server side rendering\nicon: i-lucide-brackets\n---\n\n# Nano JSX\n\n> Server-side JSX rendering in Nitro with nano-jsx.\n\n<!-- automd:ui-code-tree src=\"../../examples/nano-jsx\" default=\"server.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.tsx\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nano-jsx\": \"^0.2.1\",\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```tsx [server.tsx]\nimport { defineHandler, html } from \"nitro\";\nimport { renderSSR } from \"nano-jsx\";\n\nexport default defineHandler(() => {\n  return html(renderSSR(() => <h1>Nitro + nano-jsx works!</h1>));\n});\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"nano-jsx/esm\"\n  }\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/nano-jsx/README.md\" -->\n\n## Server Entry\n\n```tsx [server.tsx]\nimport { defineHandler, html } from \"nitro\";\nimport { renderSSR } from \"nano-jsx\";\n\nexport default defineHandler(() => {\n  return html(renderSSR(() => <h1>Nitro + nano-jsx works!</h1>));\n});\n```\n\nNitro auto-detects `server.tsx` and uses it as the server entry. Use `renderSSR` from nano-jsx to convert JSX into an HTML string. The `html` helper from H3 sets the correct content type header.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Renderer](/docs/renderer)\n- [nano-jsx](https://nanojsx.io/)\n"
  },
  {
    "path": "docs/4.examples/plugins.md",
    "content": "---\ncategory: features\nicon: i-lucide-plug\n---\n\n# Plugins\n\n> Extend Nitro with custom plugins for hooks and lifecycle events.\n\n<!-- automd:ui-code-tree src=\"../../examples/plugins\" default=\"server/plugins/test.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server/plugins/test.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { eventHandler } from \"h3\";\n\nexport default eventHandler(() => \"<h1>Hello Nitro!</h1>\");\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [server/plugins/test.ts]\nimport { definePlugin } from \"nitro\";\nimport { useNitroHooks } from \"nitro/app\";\n\nexport default definePlugin((nitroApp) => {\n  const hooks = useNitroHooks();\n  hooks.hook(\"response\", (event) => {\n    event.headers.set(\"content-type\", \"html; charset=utf-8\");\n  });\n});\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/plugins/README.md\" -->\n\nPlugins let you hook into Nitro's runtime lifecycle. This example shows a plugin that modifies the `Content-Type` header on every response. Create files in `server/plugins/` and they're automatically loaded at startup.\n\n## Defining a Plugin\n\n```ts [server/plugins/test.ts]\nimport { definePlugin } from \"nitro\";\nimport { useNitroHooks } from \"nitro/app\";\n\nexport default definePlugin((nitroApp) => {\n  const hooks = useNitroHooks();\n  hooks.hook(\"response\", (event) => {\n    event.headers.set(\"content-type\", \"html; charset=utf-8\");\n  });\n});\n```\n\nThe plugin uses `useNitroHooks()` to access the hooks system, then registers a `response` hook that runs after every request. Here it sets the content type to HTML, but you could log requests, add security headers, or modify responses in any way.\n\n## Main Handler\n\n```ts [server.ts]\nimport { eventHandler } from \"h3\";\n\nexport default eventHandler(() => \"<h1>Hello Nitro!</h1>\");\n```\n\nThe handler returns HTML without setting a content type. The plugin automatically adds the correct `Content-Type: html; charset=utf-8` header to the response.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Plugins](/docs/plugins)\n- [Lifecycle](/docs/lifecycle)\n"
  },
  {
    "path": "docs/4.examples/renderer.md",
    "content": "---\ncategory: server side rendering\nicon: i-lucide-code\n---\n\n# Custom Renderer\n\n> Build a custom HTML renderer in Nitro with server-side data fetching.\n\n<!-- automd:ui-code-tree src=\"../../examples/renderer\" default=\"renderer.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"renderer.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  renderer: { handler: \"./renderer\" },\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [renderer.ts]\nimport { fetch } from \"nitro\";\n\nexport default async function renderer({ url }: { req: Request; url: URL }) {\n  const apiRes = await fetch(\"/api/hello\").then((res) => res.text());\n  return new Response(\n    /* html */ `<!DOCTYPE html>\n    <html>\n    <head>\n      <title>Custom Renderer</title>\n    </head>\n    <body>\n      <h1>Hello from custom renderer!</h1>\n      <p>Current path: ${url.pathname}</p>\n      <p>API says: ${apiRes}</p>\n    </body>\n    </html>`,\n    { headers: { \"content-type\": \"text/html; charset=utf-8\" } }\n  );\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/renderer/README.md\" -->\n\nCreate a custom renderer that generates HTML responses with data from API routes. Use Nitro's internal `fetch` to call routes without network overhead.\n\n## Renderer\n\n```ts [renderer.ts]\nimport { fetch } from \"nitro\";\n\nexport default async function renderer({ url }: { req: Request; url: URL }) {\n  const apiRes = await fetch(\"/api/hello\").then((res) => res.text());\n  return new Response(\n    /* html */ `<!DOCTYPE html>\n    <html>\n    <head>\n      <title>Custom Renderer</title>\n    </head>\n    <body>\n      <h1>Hello from custom renderer!</h1>\n      <p>Current path: ${url.pathname}</p>\n      <p>API says: ${apiRes}</p>\n    </body>\n    </html>`,\n    { headers: { \"content-type\": \"text/html; charset=utf-8\" } }\n  );\n}\n```\n\nNitro auto-detects `renderer.ts` in your project root and uses it for all non-API routes. The renderer function receives the request URL and returns a `Response`.\n\nUse `fetch` from `nitro` to call API routes without network overhead—these requests stay in-process.\n\n## API Route\n\n```ts [api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n```\n\nDefine API routes in the `api/` directory. When the renderer calls `fetch(\"/api/hello\")`, this handler runs and returns its response.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Renderer](/docs/renderer)\n"
  },
  {
    "path": "docs/4.examples/runtime-config.md",
    "content": "---\ncategory: config\nicon: i-lucide-settings\n---\n\n# Runtime Config\n\n> Environment-aware configuration with runtime access.\n\n<!-- automd:ui-code-tree src=\"../../examples/runtime-config\" default=\"nitro.config.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"nitro.config.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  runtimeConfig: {\n    apiKey: \"\",\n  },\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n  return { runtimeConfig };\n});\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/runtime-config/README.md\" -->\n\nRuntime config lets you define configuration values that can be overridden by environment variables at runtime.\n\n## Define Config Schema\n\nDeclare your runtime config with default values in `nitro.config.ts`:\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  runtimeConfig: {\n    apiKey: \"\",\n  },\n});\n```\n\n## Access at Runtime\n\nUse `useRuntimeConfig` to access configuration values in your handlers:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n  return { runtimeConfig };\n});\n```\n\n## Environment Variables\n\nOverride config values via environment variables prefixed with `NITRO_`:\n\n```sh [.env]\n# NEVER COMMIT SENSITIVE DATA. THIS IS ONLY FOR DEMO PURPOSES.\nNITRO_API_KEY=secret-api-key\n```\n\n<!-- /automd -->\n\n## Learn More\n\n- [Configuration](/docs/configuration)\n"
  },
  {
    "path": "docs/4.examples/server-fetch.md",
    "content": "---\ncategory: features\nicon: i-lucide-arrow-right-left\n---\n\n# Server Fetch\n\n> Internal server-to-server requests without network overhead.\n\n<!-- automd:ui-code-tree src=\"../../examples/server-fetch\" default=\"routes/index.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"routes/index.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig, serverFetch } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  hooks: {\n    \"dev:start\": async () => {\n      const res = await serverFetch(\"/hello\");\n      const text = await res.text();\n      console.log(\"Fetched /hello in nitro module:\", res.status, text);\n    },\n  },\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [routes/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Hello!\");\n```\n\n```ts [routes/index.ts]\nimport { defineHandler } from \"nitro\";\nimport { fetch } from \"nitro\";\n\nexport default defineHandler(() => fetch(\"/hello\"));\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/server-fetch/README.md\" -->\n\nWhen you need one route to call another, use Nitro's `fetch` function instead of the global fetch. It makes internal requests that stay in-process, avoiding network round-trips. The request never leaves the server.\n\n## Main Route\n\n```ts [routes/index.ts]\nimport { defineHandler } from \"nitro\";\nimport { fetch } from \"nitro\";\n\nexport default defineHandler(() => fetch(\"/hello\"));\n```\n\nThe index route imports `fetch` from `nitro` (not the global fetch) and calls the `/hello` route. This request is handled internally without going through the network stack.\n\n## Internal API Route\n\n```ts [routes/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Hello!\");\n```\n\nA simple route that returns \"Hello!\". When the index route calls `fetch(\"/hello\")`, this handler runs and its response is returned directly.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Routing](/docs/routing)\n"
  },
  {
    "path": "docs/4.examples/shiki.md",
    "content": "---\ncategory: integrations\nicon: i-lucide-highlighter\n---\n\n# Shiki\n\n> Server-side syntax highlighting in Nitro with Shiki.\n\n<!-- automd:ui-code-tree src=\"../../examples/shiki\" default=\"api/highlight.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"api/highlight.ts\" expandAll}\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <title>Hello World Snippet</title>\n    <link rel=\"stylesheet\" href=\"styles.css\" />\n  </head>\n  <body>\n    <div class=\"card\" role=\"region\" aria-label=\"Code snippet\">\n      <div class=\"label\">JavaScript</div>\n      <script server>\n        const hl = (code) =>\n          serverFetch(\"/api/highlight\", {\n            method: \"POST\",\n            body: code,\n          });\n      </script>\n      <pre><code>{{{ hl(`console.log(\"💚 Simple is beautiful!\");`) }}}</code></pre>\n    </div>\n  </body>\n</html>\n```\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite dev\",\n    \"build\": \"vite build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"shiki\": \"^3.23.0\"\n  }\n}\n```\n\n```css [styles.css]\nhtml,\nbody {\n  height: 100%;\n  margin: 0;\n}\nbody {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background: #f6f8fa;\n  font-family:\n    system-ui,\n    -apple-system,\n    \"Segoe UI\",\n    Roboto,\n    \"Helvetica Neue\",\n    Arial,\n    \"Noto Sans\",\n    \"Liberation Sans\",\n    sans-serif;\n}\n.card {\n  text-align: left;\n  background: #0b1220;\n  color: #e6edf3;\n  padding: 1rem;\n  border-radius: 8px;\n  box-shadow: 0 8px 24px rgba(2, 6, 23, 0.2);\n  max-width: 90%;\n  width: 520px;\n}\n.label {\n  font-size: 12px;\n  color: #9aa7b2;\n  margin-bottom: 8px;\n}\npre {\n  margin: 0;\n  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, \"Courier New\", monospace;\n  font-size: 14px;\n  background: transparent;\n  white-space: pre;\n  overflow: auto;\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n```\n\n```ts [api/highlight.ts]\nimport { createHighlighterCore } from \"shiki/core\";\nimport { createOnigurumaEngine } from \"shiki/engine/oniguruma\";\n\nconst highlighter = await createHighlighterCore({\n  engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n  themes: [await import(\"shiki/themes/vitesse-dark.mjs\")],\n  langs: [await import(\"shiki/langs/ts.mjs\")],\n});\n\nexport default async ({ req }: { req: Request }) => {\n  const code = await req.text();\n  const html = await highlighter.codeToHtml(code, {\n    lang: \"ts\",\n    theme: \"vitesse-dark\",\n  });\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n  });\n};\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/shiki/README.md\" -->\n\nUse Shiki for syntax highlighting with TextMate grammars. This example highlights code on the server using Nitro's server scripts feature, which runs JavaScript inside HTML files before sending the response.\n\n## API Route\n\n```ts [api/highlight.ts]\nimport { createHighlighterCore } from \"shiki/core\";\nimport { createOnigurumaEngine } from \"shiki/engine/oniguruma\";\n\nconst highlighter = await createHighlighterCore({\n  engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n  themes: [await import(\"shiki/themes/vitesse-dark.mjs\")],\n  langs: [await import(\"shiki/langs/ts.mjs\")],\n});\n\nexport default async ({ req }: { req: Request }) => {\n  const code = await req.text();\n  const html = await highlighter.codeToHtml(code, {\n    lang: \"ts\",\n    theme: \"vitesse-dark\",\n  });\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n  });\n};\n```\n\nCreate a Shiki highlighter with the Vitesse Dark theme and TypeScript language support. When the API receives a POST request, it reads the code from the request body and returns highlighted HTML.\n\n## Server-Side Rendering\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <title>Hello World Snippet</title>\n    <link rel=\"stylesheet\" href=\"styles.css\" />\n  </head>\n  <body>\n    <div class=\"card\" role=\"region\" aria-label=\"Code snippet\">\n      <div class=\"label\">JavaScript</div>\n      <script server>\n        const hl = (code) =>\n          serverFetch(\"/api/highlight\", {\n            method: \"POST\",\n            body: code,\n          });\n      </script>\n      <pre><code>{{{ hl(`console.log(\"💚 Simple is beautiful!\");`) }}}</code></pre>\n    </div>\n  </body>\n</html>\n```\n\nThe `<script server>` tag runs on the server before the HTML is sent. It defines a helper function that calls the highlight API using `serverFetch`. The triple-brace syntax `{{{ }}}` outputs the result without escaping, so the highlighted HTML renders correctly.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Shiki](https://shiki.style/)\n"
  },
  {
    "path": "docs/4.examples/virtual-routes.md",
    "content": "---\ncategory: features\nicon: i-lucide-box\n---\n\n# Virtual Routes\n\n> Define routes programmatically using Nitro's virtual module system.\n\n<!-- automd:ui-code-tree src=\"../../examples/virtual-routes\" default=\"nitro.config.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"nitro.config.ts\" expandAll}\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  routes: {\n    \"/\": \"#virtual-route\",\n  },\n  virtual: {\n    \"#virtual-route\": () =>\n      /* js */ `export default () => new Response(\"Hello from virtual entry!\")`,\n  },\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\",\n    \"preview\": \"node .output/server/index.mjs\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/virtual-routes/README.md\" -->\n\nVirtual routes let you define handlers as strings in your config instead of creating separate files. This is useful when generating routes dynamically, building plugins, or keeping simple routes inline.\n\n## Configuration\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  routes: {\n    \"/\": \"#virtual-route\",\n  },\n  virtual: {\n    \"#virtual-route\": () =>\n      /* js */ `export default () => new Response(\"Hello from virtual entry!\")`,\n  },\n});\n```\n\nThe `routes` option maps URL paths to virtual module identifiers (prefixed with `#`). The `virtual` option defines the module content as a string or function returning a string. At build time, Nitro resolves these virtual modules to actual handlers.\n\nThere are no route files in this project. The entire handler is defined inline in the config, and Nitro generates the route at build time.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Routing](/docs/routing)\n- [Configuration](/docs/configuration)\n"
  },
  {
    "path": "docs/4.examples/vite-nitro-plugin.md",
    "content": "---\ncategory: vite\nicon: i-logos-vitejs\n---\n\n# Vite Nitro Plugin\n\n> Use Nitro as a Vite plugin for programmatic configuration.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-nitro-plugin\" default=\"vite.config.mjs\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"vite.config.mjs\" expandAll}\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"vite\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro(),\n    {\n      name: \"my-nitro-plugin\",\n      nitro: {\n        setup: (nitro) => {\n          nitro.options.routes[\"/\"] = \"#virtual-by-plugin\";\n          nitro.options.virtual[\"#virtual-by-plugin\"] =\n            `export default () => new Response(\"Hello from virtual entry!\")`;\n        },\n      },\n    },\n  ],\n});\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-nitro-plugin/README.md\" -->\n\nInstead of using a separate `nitro.config.ts`, you can configure Nitro directly in your Vite config. This gives you access to Nitro's setup hook where you can register routes and virtual modules programmatically.\n\n## Vite Configuration\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro(),\n    {\n      name: \"my-nitro-plugin\",\n      nitro: {\n        setup: (nitro) => {\n          nitro.options.routes[\"/\"] = \"#virtual-by-plugin\";\n          nitro.options.virtual[\"#virtual-by-plugin\"] =\n            `export default () => new Response(\"Hello from virtual entry!\")`;\n        },\n      },\n    },\n  ],\n});\n```\n\nThe config adds two plugins: the `nitro()` plugin and a custom plugin that uses the `nitro.setup` hook. Inside the setup function, you have access to Nitro's options object. This example registers a virtual route at `/` that maps to a virtual module `#virtual-by-plugin`, then defines that module inline.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Configuration](/docs/configuration)\n"
  },
  {
    "path": "docs/4.examples/vite-rsc.md",
    "content": "---\ncategory: vite\nicon: i-logos-react\n---\n\n# Vite RSC\n\n> React Server Components with Vite and Nitro.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-rsc\" default=\"app/root.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"app/root.tsx\" expandAll}\n\n```json [package.json]\n{\n  \"name\": \"@vitejs/plugin-rsc-examples-starter\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"@vitejs/plugin-rsc\": \"^0.5.21\",\n    \"nitro\": \"latest\",\n    \"rsc-html-stream\": \"^0.0.7\",\n    \"vite\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n    \"types\": [\"vite/client\", \"@vitejs/plugin-rsc/types\"],\n    \"jsx\": \"react-jsx\"\n  }\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nimport rsc from \"@vitejs/plugin-rsc\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n  plugins: [\n    nitro(),\n    rsc({\n      serverHandler: false,\n      entries: {\n        ssr: \"./app/framework/entry.ssr.tsx\",\n        rsc: \"./app/framework/entry.rsc.tsx\",\n      },\n    }),\n    react(),\n  ],\n\n  environments: {\n    client: {\n      build: {\n        rollupOptions: {\n          input: { index: \"./app/framework/entry.browser.tsx\" },\n        },\n      },\n    },\n  },\n});\n```\n\n```tsx [app/action.tsx]\n\"use server\";\n\nlet serverCounter = 0;\n\nexport async function getServerCounter() {\n  return serverCounter;\n}\n\nexport async function updateServerCounter(change: number) {\n  serverCounter += change;\n}\n```\n\n```tsx [app/client.tsx]\n\"use client\";\n\nimport React from \"react\";\n\nexport function ClientCounter() {\n  const [count, setCount] = React.useState(0);\n\n  return <button onClick={() => setCount((count) => count + 1)}>Client Counter: {count}</button>;\n}\n```\n\n```css [app/index.css]\n:root {\n  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;\n  line-height: 1.5;\n  font-weight: 400;\n\n  color-scheme: light dark;\n  color: rgba(255, 255, 255, 0.87);\n  background-color: #242424;\n\n  font-synthesis: none;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\na {\n  font-weight: 500;\n  color: #646cff;\n  text-decoration: inherit;\n}\na:hover {\n  color: #535bf2;\n}\n\nbody {\n  margin: 0;\n  display: flex;\n  place-items: center;\n  min-width: 320px;\n  min-height: 100vh;\n}\n\nh1 {\n  font-size: 3.2em;\n  line-height: 1.1;\n}\n\nbutton {\n  border-radius: 8px;\n  border: 1px solid transparent;\n  padding: 0.6em 1.2em;\n  font-size: 1em;\n  font-weight: 500;\n  font-family: inherit;\n  background-color: #1a1a1a;\n  cursor: pointer;\n  transition: border-color 0.25s;\n}\nbutton:hover {\n  border-color: #646cff;\n}\nbutton:focus,\nbutton:focus-visible {\n  outline: 4px auto -webkit-focus-ring-color;\n}\n\n@media (prefers-color-scheme: light) {\n  :root {\n    color: #213547;\n    background-color: #ffffff;\n  }\n  a:hover {\n    color: #747bff;\n  }\n  button {\n    background-color: #f9f9f9;\n  }\n}\n\n#root {\n  max-width: 1280px;\n  margin: 0 auto;\n  padding: 2rem;\n  text-align: center;\n}\n\n.logo {\n  height: 6em;\n  padding: 1.5em;\n  will-change: filter;\n  transition: filter 300ms;\n}\n.logo:hover {\n  filter: drop-shadow(0 0 2em #646cffaa);\n}\n.logo.react:hover {\n  filter: drop-shadow(0 0 2em #61dafbaa);\n}\n\n@keyframes logo-spin {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  a:nth-of-type(2) .logo {\n    animation: logo-spin infinite 20s linear;\n  }\n}\n\n.card {\n  padding: 1rem;\n}\n\n.read-the-docs {\n  color: #888;\n  text-align: left;\n}\n```\n\n```tsx [app/root.tsx]\nimport \"./index.css\"; // css import is automatically injected in exported server components\nimport viteLogo from \"./assets/vite.svg\";\nimport { getServerCounter, updateServerCounter } from \"./action.tsx\";\nimport reactLogo from \"./assets/react.svg\";\nimport nitroLogo from \"./assets/nitro.svg\";\nimport { ClientCounter } from \"./client.tsx\";\n\nexport function Root(props: { url: URL }) {\n  return (\n    <html lang=\"en\">\n      <head>\n        {/* eslint-disable-next-line unicorn/text-encoding-identifier-case */}\n        <meta charSet=\"UTF-8\" />\n        <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <title>Nitro + Vite + RSC</title>\n      </head>\n      <body>\n        <App {...props} />\n      </body>\n    </html>\n  );\n}\n\nfunction App(props: { url: URL }) {\n  return (\n    <div id=\"root\">\n      <div>\n        <a href=\"https://vite.dev\" target=\"_blank\">\n          <img src={viteLogo} className=\"logo\" alt=\"Vite logo\" />\n        </a>\n        <a href=\"https://react.dev/reference/rsc/server-components\" target=\"_blank\">\n          <img src={reactLogo} className=\"logo react\" alt=\"React logo\" />\n        </a>\n\n        <a href=\"https://nitro.build\" target=\"_blank\">\n          <img src={nitroLogo} className=\"logo\" alt=\"Nitro logo\" />\n        </a>\n      </div>\n      <h1>Vite + RSC + Nitro</h1>\n      <div className=\"card\">\n        <ClientCounter />\n      </div>\n      <div className=\"card\">\n        <form action={updateServerCounter.bind(null, 1)}>\n          <button>Server Counter: {getServerCounter()}</button>\n        </form>\n      </div>\n      <div className=\"card\">Request URL: {props.url?.href}</div>\n      <ul className=\"read-the-docs\">\n        <li>\n          Edit <code>src/client.tsx</code> to test client HMR.\n        </li>\n        <li>\n          Edit <code>src/root.tsx</code> to test server HMR.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"./_.rsc\" target=\"_blank\">\n            <code>_.rsc</code>\n          </a>{\" \"}\n          to view RSC stream payload.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"?__nojs\" target=\"_blank\">\n            <code>?__nojs</code>\n          </a>{\" \"}\n          to test server action without js enabled.\n        </li>\n      </ul>\n    </div>\n  );\n}\n```\n\n```text [app/assets/nitro.svg]\n<!-- nitro logo -->\n<svg width=\"40\" height=\"40\" viewBox=\"0 0 40 40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n  <g clip-path=\"url(#clip0_115_108)\">\n    <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n      d=\"M35.2166 7.02016C28.0478 -1.38317 15.4241 -2.38397 7.02077 4.78481C-1.38256 11.9536 -2.38336 24.5773 4.78542 32.9806C11.9542 41.3839 24.5779 42.3847 32.9812 35.216C41.3846 28.0472 42.3854 15.4235 35.2166 7.02016ZM25.2525 17.5175C26.0233 17.5175 26.5155 18.3527 26.1287 19.0194L26.0175 19.2111L18.4696 31.6294C18.3293 31.8602 18.0788 32.001 17.8088 32.001H17.0883C16.5946 32.001 16.2336 31.5349 16.3573 31.0569L18.4054 23.1384C18.5691 22.5053 18.0912 21.888 17.4373 21.888H14.2914C13.6375 21.888 13.1596 21.2708 13.3232 20.6377L16.4137 8.68289C16.5261 8.28056 16.8904 7.99734 17.3081 8.00208C17.3587 8.00266 17.4046 8.0035 17.4427 8.0047L20.6109 8.00465C21.217 8.00436 21.684 8.53896 21.6023 9.13949L21.5828 9.28246L20.3746 16.349C20.2702 16.9598 20.7406 17.5175 21.3603 17.5175H25.2525Z\"\n      fill=\"url(#paint0_diamond_115_108)\" />\n    <mask id=\"mask0_115_108\" style=\"mask-type:alpha\" maskUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\"\n      width=\"40\" height=\"41\">\n      <circle cx=\"20\" cy=\"20.001\" r=\"20\" fill=\"url(#paint1_diamond_115_108)\" />\n    </mask>\n    <g mask=\"url(#mask0_115_108)\">\n      <g filter=\"url(#filter0_f_115_108)\">\n        <path\n          d=\"M1.11145 13.4267C0.0703174 16.4179 -0.245523 19.6136 0.189923 22.7507C0.62537 25.8879 1.79965 28.8768 3.61611 31.4713C5.43256 34.0659 7.83925 36.192 10.6381 37.6746C13.4369 39.1572 16.5478 39.9538 19.7147 39.999C22.8816 40.0442 26.0139 39.3366 28.8539 37.9345C31.6939 36.5324 34.1602 34.4758 36.05 31.9341C37.9397 29.3924 39.1988 26.4383 39.7236 23.3148C40.2483 20.1914 40.0238 16.9879 39.0684 13.9682L33.2532 15.808C33.9172 17.9068 34.0732 20.1333 33.7085 22.3042C33.3438 24.4751 32.4687 26.5283 31.1552 28.2949C29.8418 30.0615 28.1276 31.4908 26.1537 32.4653C24.1799 33.4399 22.0028 33.9316 19.8017 33.9002C17.6006 33.8688 15.4384 33.3151 13.4932 32.2847C11.5479 31.2543 9.87518 29.7766 8.61269 27.9733C7.35019 26.1699 6.53403 24.0926 6.23138 21.9122C5.92873 19.7317 6.14825 17.5106 6.87187 15.4316L1.11145 13.4267Z\"\n          fill=\"white\" />\n      </g>\n    </g>\n  </g>\n  <defs>\n    <filter id=\"filter0_f_115_108\" x=\"-10\" y=\"3.42667\" width=\"60\" height=\"46.5744\"\n      filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\">\n      <feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\" />\n      <feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\" />\n      <feGaussianBlur stdDeviation=\"5\" result=\"effect1_foregroundBlur_115_108\" />\n    </filter>\n    <radialGradient id=\"paint0_diamond_115_108\" cx=\"0\" cy=\"0\" r=\"1\" gradientUnits=\"userSpaceOnUse\"\n      gradientTransform=\"translate(4.00069 20.0004) scale(39.0007 397.71)\">\n      <stop stop-color=\"#31B2F3\" />\n      <stop offset=\"0.473958\" stop-color=\"#F27CEC\" />\n      <stop offset=\"1\" stop-color=\"#FD6641\" />\n    </radialGradient>\n    <radialGradient id=\"paint1_diamond_115_108\" cx=\"0\" cy=\"0\" r=\"1\" gradientUnits=\"userSpaceOnUse\"\n      gradientTransform=\"translate(4 20.0011) scale(39 397.703)\">\n      <stop stop-color=\"#F27CEC\" />\n      <stop offset=\"0.484375\" stop-color=\"#31B2F3\" />\n      <stop offset=\"1\" stop-color=\"#7D7573\" />\n    </radialGradient>\n    <clipPath id=\"clip0_115_108\">\n      <rect width=\"146\" height=\"40.001\" fill=\"white\" />\n    </clipPath>\n  </defs>\n</svg>\n```\n\n```text [app/assets/react.svg]\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-hidden=\"true\" role=\"img\" class=\"iconify iconify--logos\" width=\"35.93\" height=\"32\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 256 228\"><path fill=\"#00D8FF\" d=\"M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z\"></path></svg>\n```\n\n```text [app/assets/vite.svg]\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" aria-hidden=\"true\" role=\"img\" class=\"iconify iconify--logos\" width=\"31.88\" height=\"32\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 256 257\"><defs><linearGradient id=\"IconifyId1813088fe1fbc01fb466\" x1=\"-.828%\" x2=\"57.636%\" y1=\"7.652%\" y2=\"78.411%\"><stop offset=\"0%\" stop-color=\"#41D1FF\"></stop><stop offset=\"100%\" stop-color=\"#BD34FE\"></stop></linearGradient><linearGradient id=\"IconifyId1813088fe1fbc01fb467\" x1=\"43.376%\" x2=\"50.316%\" y1=\"2.242%\" y2=\"89.03%\"><stop offset=\"0%\" stop-color=\"#FFEA83\"></stop><stop offset=\"8.333%\" stop-color=\"#FFDD35\"></stop><stop offset=\"100%\" stop-color=\"#FFA800\"></stop></linearGradient></defs><path fill=\"url(#IconifyId1813088fe1fbc01fb466)\" d=\"M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z\"></path><path fill=\"url(#IconifyId1813088fe1fbc01fb467)\" d=\"M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z\"></path></svg>\n```\n\n```tsx [app/framework/entry.browser.tsx]\nimport {\n  createFromReadableStream,\n  createFromFetch,\n  setServerCallback,\n  createTemporaryReferenceSet,\n  encodeReply,\n} from \"@vitejs/plugin-rsc/browser\";\nimport React from \"react\";\nimport { createRoot, hydrateRoot } from \"react-dom/client\";\nimport { rscStream } from \"rsc-html-stream/client\";\nimport { GlobalErrorBoundary } from \"./error-boundary\";\nimport type { RscPayload } from \"./entry.rsc\";\nimport { createRscRenderRequest } from \"./request\";\n\nasync function main() {\n  // Stash `setPayload` function to trigger re-rendering\n  // from outside of `BrowserRoot` component (e.g. server function call, navigation, hmr)\n  let setPayload: (v: RscPayload) => void;\n\n  // Deserialize RSC stream back to React VDOM for CSR\n  const initialPayload = await createFromReadableStream<RscPayload>(\n    // Initial RSC stream is injected in SSR stream as <script>...FLIGHT_DATA...</script>\n    rscStream\n  );\n\n  // Browser root component to (re-)render RSC payload as state\n  function BrowserRoot() {\n    const [payload, setPayload_] = React.useState(initialPayload);\n\n    React.useEffect(() => {\n      setPayload = (v) => React.startTransition(() => setPayload_(v));\n    }, [setPayload_]);\n\n    // Re-fetch/render on client side navigation\n    React.useEffect(() => {\n      return listenNavigation(() => fetchRscPayload());\n    }, []);\n\n    return payload.root;\n  }\n\n  // Re-fetch RSC and trigger re-rendering\n  async function fetchRscPayload() {\n    const renderRequest = createRscRenderRequest(globalThis.location.href);\n    const payload = await createFromFetch<RscPayload>(fetch(renderRequest));\n    setPayload(payload);\n  }\n\n  // Register a handler which will be internally called by React\n  // on server function request after hydration.\n  setServerCallback(async (id, args) => {\n    const temporaryReferences = createTemporaryReferenceSet();\n    const renderRequest = createRscRenderRequest(globalThis.location.href, {\n      id,\n      body: await encodeReply(args, { temporaryReferences }),\n    });\n    const payload = await createFromFetch<RscPayload>(fetch(renderRequest), {\n      temporaryReferences,\n    });\n    setPayload(payload);\n    const { ok, data } = payload.returnValue!;\n    if (!ok) throw data;\n    return data;\n  });\n\n  // Hydration\n  const browserRoot = (\n    <React.StrictMode>\n      <GlobalErrorBoundary>\n        <BrowserRoot />\n      </GlobalErrorBoundary>\n    </React.StrictMode>\n  );\n  if (\"__NO_HYDRATE\" in globalThis) {\n    createRoot(document).render(browserRoot);\n  } else {\n    hydrateRoot(document, browserRoot, {\n      formState: initialPayload.formState,\n    });\n  }\n\n  // Implement server HMR by triggering re-fetch/render of RSC upon server code change\n  if (import.meta.hot) {\n    import.meta.hot.on(\"rsc:update\", () => {\n      fetchRscPayload();\n    });\n  }\n}\n\n// A little helper to setup events interception for client side navigation\nfunction listenNavigation(onNavigation: () => void) {\n  globalThis.addEventListener(\"popstate\", onNavigation);\n\n  const oldPushState = globalThis.history.pushState;\n  globalThis.history.pushState = function (...args) {\n    const res = oldPushState.apply(this, args);\n    onNavigation();\n    return res;\n  };\n\n  const oldReplaceState = globalThis.history.replaceState;\n  globalThis.history.replaceState = function (...args) {\n    const res = oldReplaceState.apply(this, args);\n    onNavigation();\n    return res;\n  };\n\n  function onClick(e: MouseEvent) {\n    const link = (e.target as Element).closest(\"a\");\n    if (\n      link &&\n      link instanceof HTMLAnchorElement &&\n      link.href &&\n      (!link.target || link.target === \"_self\") &&\n      link.origin === location.origin &&\n      !link.hasAttribute(\"download\") &&\n      e.button === 0 && // left clicks only\n      !e.metaKey && // open in new tab (mac)\n      !e.ctrlKey && // open in new tab (windows)\n      !e.altKey && // download\n      !e.shiftKey &&\n      !e.defaultPrevented\n    ) {\n      e.preventDefault();\n      history.pushState(null, \"\", link.href);\n    }\n  }\n  document.addEventListener(\"click\", onClick);\n\n  return () => {\n    document.removeEventListener(\"click\", onClick);\n    globalThis.removeEventListener(\"popstate\", onNavigation);\n    globalThis.history.pushState = oldPushState;\n    globalThis.history.replaceState = oldReplaceState;\n  };\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain();\n```\n\n```tsx [app/framework/entry.rsc.tsx]\nimport {\n  renderToReadableStream,\n  createTemporaryReferenceSet,\n  decodeReply,\n  loadServerAction,\n  decodeAction,\n  decodeFormState,\n} from \"@vitejs/plugin-rsc/rsc\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { Root } from \"../root.tsx\";\nimport { parseRenderRequest } from \"./request.tsx\";\n\n// The schema of payload which is serialized into RSC stream on rsc environment\n// and deserialized on ssr/client environments.\nexport type RscPayload = {\n  // this demo renders/serializes/deserializes entire root html element\n  // but this mechanism can be changed to render/fetch different parts of components\n  // based on your own route conventions.\n  root: React.ReactNode;\n\n  // Server action return value of non-progressive enhancement case\n  returnValue?: { ok: boolean; data: unknown };\n\n  // Server action form state (e.g. useActionState) of progressive enhancement case\n  formState?: ReactFormState;\n};\n\n// The plugin by default assumes `rsc` entry having default export of request handler.\n// however, how server entries are executed can be customized by registering own server handler.\nexport default async function handler(request: Request): Promise<Response> {\n  // Differentiate RSC, SSR, action, etc.\n  const renderRequest = parseRenderRequest(request);\n  request = renderRequest.request;\n\n  // Handle server function request\n  let returnValue: RscPayload[\"returnValue\"] | undefined;\n  let formState: ReactFormState | undefined;\n  let temporaryReferences: unknown | undefined;\n  let actionStatus: number | undefined;\n\n  if (renderRequest.isAction === true) {\n    if (renderRequest.actionId) {\n      // Action is called via `ReactClient.setServerCallback`.\n      const contentType = request.headers.get(\"content-type\");\n      const body = contentType?.startsWith(\"multipart/form-data\")\n        ? await request.formData()\n        : await request.text();\n      temporaryReferences = createTemporaryReferenceSet();\n      const args = await decodeReply(body, { temporaryReferences });\n      const action = await loadServerAction(renderRequest.actionId);\n      try {\n        // eslint-disable-next-line prefer-spread\n        const data = await action.apply(null, args);\n        returnValue = { ok: true, data };\n      } catch (error_) {\n        returnValue = { ok: false, data: error_ };\n        actionStatus = 500;\n      }\n    } else {\n      // Otherwise server function is called via `<form action={...}>`\n      // before hydration (e.g. when JavaScript is disabled).\n      // aka progressive enhancement.\n      const formData = await request.formData();\n      const decodedAction = await decodeAction(formData);\n      try {\n        const result = await decodedAction();\n        formState = await decodeFormState(result, formData);\n      } catch {\n        // there's no single general obvious way to surface this error,\n        // so explicitly return classic 500 response.\n        return new Response(\"Internal Server Error: server action failed\", {\n          status: 500,\n        });\n      }\n    }\n  }\n\n  // Serialization from React VDOM tree to RSC stream.\n  // We render RSC stream after handling server function request\n  // so that new render reflects updated state from server function call\n  // to achieve single round trip to mutate and fetch from server.\n  const rscPayload: RscPayload = {\n    root: <Root url={renderRequest.url} />,\n    formState,\n    returnValue,\n  };\n\n  const rscOptions = { temporaryReferences };\n  const rscStream = renderToReadableStream<RscPayload>(rscPayload, rscOptions);\n\n  // Respond RSC stream without HTML rendering as decided by `RenderRequest`\n  if (renderRequest.isRsc) {\n    return new Response(rscStream, {\n      status: actionStatus,\n      headers: {\n        \"content-type\": \"text/x-component;charset=utf-8\",\n      },\n    });\n  }\n\n  // Delegate to SSR environment for HTML rendering.\n  // The plugin provides `loadModule` helper to allow loading SSR environment entry module\n  // in RSC environment. however this can be customized by implementing own runtime communication\n  // e.g. `@cloudflare/vite-plugin`'s service binding.\n  const ssrEntryModule = await import.meta.viteRsc.loadModule<typeof import(\"./entry.ssr.tsx\")>(\n    \"ssr\",\n    \"index\"\n  );\n\n  const ssrResult = await ssrEntryModule.renderHTML(rscStream, {\n    formState,\n    // Allow quick simulation of JavaScript disabled browser\n    debugNoJS: renderRequest.url.searchParams.has(\"__nojs\"),\n  });\n\n  // Respond HTML\n  return new Response(ssrResult.stream, {\n    status: ssrResult.status,\n    headers: {\n      \"Content-Type\": \"text/html\",\n    },\n  });\n}\n\nif (import.meta.hot) {\n  import.meta.hot.accept();\n}\n```\n\n```tsx [app/framework/entry.ssr.tsx]\nimport { createFromReadableStream } from \"@vitejs/plugin-rsc/ssr\";\nimport React from \"react\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { injectRSCPayload } from \"rsc-html-stream/server\";\nimport type { RscPayload } from \"./entry.rsc\";\n\nexport default {\n  fetch: async (request: Request) => {\n    const rscEntryModule = await import.meta.viteRsc.loadModule<typeof import(\"./entry.rsc\")>(\n      \"rsc\",\n      \"index\"\n    );\n    return rscEntryModule.default(request);\n  },\n};\n\nexport async function renderHTML(\n  rscStream: ReadableStream<Uint8Array>,\n  options: {\n    formState?: ReactFormState;\n    nonce?: string;\n    debugNoJS?: boolean;\n  }\n): Promise<{ stream: ReadableStream<Uint8Array>; status?: number }> {\n  // Duplicate one RSC stream into two.\n  // - one for SSR (ReactClient.createFromReadableStream below)\n  // - another for browser hydration payload by injecting <script>...FLIGHT_DATA...</script>.\n  const [rscStream1, rscStream2] = rscStream.tee();\n\n  // Deserialize RSC stream back to React VDOM\n  let payload: Promise<RscPayload> | undefined;\n  function SsrRoot() {\n    // Deserialization needs to be kicked off inside ReactDOMServer context\n    // for ReactDOMServer preinit/preloading to work\n    payload ??= createFromReadableStream<RscPayload>(rscStream1);\n    return React.use(payload).root;\n  }\n\n  // Render HTML (traditional SSR)\n  const bootstrapScriptContent = await import.meta.viteRsc.loadBootstrapScriptContent(\"index\");\n\n  let htmlStream: ReadableStream<Uint8Array>;\n  let status: number | undefined;\n\n  try {\n    htmlStream = await renderToReadableStream(<SsrRoot />, {\n      bootstrapScriptContent: options?.debugNoJS ? undefined : bootstrapScriptContent,\n      nonce: options?.nonce,\n      formState: options?.formState,\n    });\n  } catch {\n    // fallback to render an empty shell and run pure CSR on browser,\n    // which can replay server component error and trigger error boundary.\n    status = 500;\n    htmlStream = await renderToReadableStream(\n      <html>\n        <body>\n          <noscript>Internal Server Error: SSR failed</noscript>\n        </body>\n      </html>,\n      {\n        bootstrapScriptContent:\n          `self.__NO_HYDRATE=1;` + (options?.debugNoJS ? \"\" : bootstrapScriptContent),\n        nonce: options?.nonce,\n      }\n    );\n  }\n\n  let responseStream: ReadableStream<Uint8Array> = htmlStream;\n  if (!options?.debugNoJS) {\n    // Initial RSC stream is injected in HTML stream as <script>...FLIGHT_DATA...</script>\n    // using utility made by devongovett https://github.com/devongovett/rsc-html-stream\n    responseStream = responseStream.pipeThrough(\n      injectRSCPayload(rscStream2, {\n        nonce: options?.nonce,\n      })\n    );\n  }\n\n  return { stream: responseStream, status };\n}\n```\n\n```tsx [app/framework/error-boundary.tsx]\n\"use client\";\n\nimport React from \"react\";\n\n// Minimal ErrorBoundary example to handle errors globally on browser\nexport function GlobalErrorBoundary(props: { children?: React.ReactNode }) {\n  return <ErrorBoundary errorComponent={DefaultGlobalErrorPage}>{props.children}</ErrorBoundary>;\n}\n\n// https://github.com/vercel/next.js/blob/33f8428f7066bf8b2ec61f025427ceb2a54c4bdf/packages/next/src/client/components/error-boundary.tsx\n// https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary\nclass ErrorBoundary extends React.Component<{\n  children?: React.ReactNode;\n  errorComponent: React.FC<{\n    error: Error;\n    reset: () => void;\n  }>;\n}> {\n  override state: { error?: Error } = {};\n\n  static getDerivedStateFromError(error: Error) {\n    return { error };\n  }\n\n  reset = () => {\n    this.setState({ error: null });\n  };\n\n  override render() {\n    const error = this.state.error;\n    if (error) {\n      return <this.props.errorComponent error={error} reset={this.reset} />;\n    }\n    return this.props.children;\n  }\n}\n\n// https://github.com/vercel/next.js/blob/677c9b372faef680d17e9ba224743f44e1107661/packages/next/src/build/webpack/loaders/next-app-loader.ts#L73\n// https://github.com/vercel/next.js/blob/677c9b372faef680d17e9ba224743f44e1107661/packages/next/src/client/components/error-boundary.tsx#L145\nfunction DefaultGlobalErrorPage(props: { error: Error; reset: () => void }) {\n  return (\n    <html>\n      <head>\n        <title>Unexpected Error</title>\n      </head>\n      <body\n        style={{\n          height: \"100vh\",\n          display: \"flex\",\n          flexDirection: \"column\",\n          placeContent: \"center\",\n          placeItems: \"center\",\n          fontSize: \"16px\",\n          fontWeight: 400,\n          lineHeight: \"24px\",\n        }}\n      >\n        <p>Caught an unexpected error</p>\n        <pre>\n          Error:{\" \"}\n          {import.meta.env.DEV && \"message\" in props.error ? props.error.message : \"(Unknown)\"}\n        </pre>\n        <button\n          onClick={() => {\n            React.startTransition(() => {\n              props.reset();\n            });\n          }}\n        >\n          Reset\n        </button>\n      </body>\n    </html>\n  );\n}\n```\n\n```tsx [app/framework/request.tsx]\n// Framework conventions (arbitrary choices for this demo):\n// - Use `_.rsc` URL suffix to differentiate RSC requests from SSR requests\n// - Use `x-rsc-action` header to pass server action ID\nconst URL_POSTFIX = \"_.rsc\";\nconst HEADER_ACTION_ID = \"x-rsc-action\";\n\n// Parsed request information used to route between RSC/SSR rendering and action handling.\n// Created by parseRenderRequest() from incoming HTTP requests.\ntype RenderRequest = {\n  isRsc: boolean; // true if request should return RSC payload (via _.rsc suffix)\n  isAction: boolean; // true if this is a server action call (POST request)\n  actionId?: string; // server action ID from x-rsc-action header\n  request: Request; // normalized Request with _.rsc suffix removed from URL\n  url: URL; // normalized URL with _.rsc suffix removed\n};\n\nexport function createRscRenderRequest(\n  urlString: string,\n  action?: { id: string; body: BodyInit }\n): Request {\n  const url = new URL(urlString);\n  url.pathname += URL_POSTFIX;\n  const headers = new Headers();\n  if (action) {\n    headers.set(HEADER_ACTION_ID, action.id);\n  }\n  return new Request(url.toString(), {\n    method: action ? \"POST\" : \"GET\",\n    headers,\n    body: action?.body,\n  });\n}\n\nexport function parseRenderRequest(request: Request): RenderRequest {\n  const url = new URL(request.url);\n  const isAction = request.method === \"POST\";\n  if (url.pathname.endsWith(URL_POSTFIX)) {\n    url.pathname = url.pathname.slice(0, -URL_POSTFIX.length);\n    const actionId = request.headers.get(HEADER_ACTION_ID) || undefined;\n    if (request.method === \"POST\" && !actionId) {\n      throw new Error(\"Missing action id header for RSC action request\");\n    }\n    return {\n      isRsc: true,\n      isAction,\n      actionId,\n      request: new Request(url, request),\n      url,\n    };\n  } else {\n    return {\n      isRsc: false,\n      isAction,\n      request,\n      url,\n    };\n  }\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-rsc/README.md\" -->\n\nThis example demonstrates React Server Components (RSC) using Vite's experimental RSC plugin with Nitro. It includes server components, client components, server actions, and streaming SSR.\n\n## Overview\n\n1. **SSR Entry** handles incoming requests and renders React components to HTML\n2. **Root Component** defines the page structure as a server component\n3. **Client Components** use the `\"use client\"` directive for interactive parts\n\n## 1. SSR Entry\n\n```tsx [app/framework/entry.ssr.tsx]\nimport { createFromReadableStream } from \"@vitejs/plugin-rsc/ssr\";\nimport React from \"react\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { injectRSCPayload } from \"rsc-html-stream/server\";\nimport type { RscPayload } from \"./entry.rsc\";\n\nexport default {\n  fetch: async (request: Request) => {\n    const rscEntryModule = await import.meta.viteRsc.loadModule<typeof import(\"./entry.rsc\")>(\n      \"rsc\",\n      \"index\"\n    );\n    return rscEntryModule.default(request);\n  },\n};\n\nexport async function renderHTML(\n  rscStream: ReadableStream<Uint8Array>,\n  options: {\n    formState?: ReactFormState;\n    nonce?: string;\n    debugNoJS?: boolean;\n  }\n): Promise<{ stream: ReadableStream<Uint8Array>; status?: number }> {\n  // Duplicate one RSC stream into two.\n  // - one for SSR (ReactClient.createFromReadableStream below)\n  // - another for browser hydration payload by injecting <script>...FLIGHT_DATA...</script>.\n  const [rscStream1, rscStream2] = rscStream.tee();\n\n  // Deserialize RSC stream back to React VDOM\n  let payload: Promise<RscPayload> | undefined;\n  function SsrRoot() {\n    // Deserialization needs to be kicked off inside ReactDOMServer context\n    // for ReactDOMServer preinit/preloading to work\n    payload ??= createFromReadableStream<RscPayload>(rscStream1);\n    return React.use(payload).root;\n  }\n\n  // Render HTML (traditional SSR)\n  const bootstrapScriptContent = await import.meta.viteRsc.loadBootstrapScriptContent(\"index\");\n\n  let htmlStream: ReadableStream<Uint8Array>;\n  let status: number | undefined;\n\n  try {\n    htmlStream = await renderToReadableStream(<SsrRoot />, {\n      bootstrapScriptContent: options?.debugNoJS ? undefined : bootstrapScriptContent,\n      nonce: options?.nonce,\n      formState: options?.formState,\n    });\n  } catch {\n    // fallback to render an empty shell and run pure CSR on browser,\n    // which can replay server component error and trigger error boundary.\n    status = 500;\n    htmlStream = await renderToReadableStream(\n      <html>\n        <body>\n          <noscript>Internal Server Error: SSR failed</noscript>\n        </body>\n      </html>,\n      {\n        bootstrapScriptContent:\n          `self.__NO_HYDRATE=1;` + (options?.debugNoJS ? \"\" : bootstrapScriptContent),\n        nonce: options?.nonce,\n      }\n    );\n  }\n\n  let responseStream: ReadableStream<Uint8Array> = htmlStream;\n  if (!options?.debugNoJS) {\n    // Initial RSC stream is injected in HTML stream as <script>...FLIGHT_DATA...</script>\n    // using utility made by devongovett https://github.com/devongovett/rsc-html-stream\n    responseStream = responseStream.pipeThrough(\n      injectRSCPayload(rscStream2, {\n        nonce: options?.nonce,\n      })\n    );\n  }\n\n  return { stream: responseStream, status };\n}\n```\n\nThe SSR entry handles the rendering pipeline. It loads the RSC entry module, duplicates the RSC stream (one for SSR, one for hydration), deserializes the stream back to React VDOM, and renders it to HTML. The RSC payload is injected into the HTML for client hydration.\n\n## 2. Root Server Component\n\n```tsx [app/root.tsx]\nimport \"./index.css\"; // css import is automatically injected in exported server components\nimport viteLogo from \"./assets/vite.svg\";\nimport { getServerCounter, updateServerCounter } from \"./action.tsx\";\nimport reactLogo from \"./assets/react.svg\";\nimport nitroLogo from \"./assets/nitro.svg\";\nimport { ClientCounter } from \"./client.tsx\";\n\nexport function Root(props: { url: URL }) {\n  return (\n    <html lang=\"en\">\n      <head>\n        {/* eslint-disable-next-line unicorn/text-encoding-identifier-case */}\n        <meta charSet=\"UTF-8\" />\n        <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <title>Nitro + Vite + RSC</title>\n      </head>\n      <body>\n        <App {...props} />\n      </body>\n    </html>\n  );\n}\n\nfunction App(props: { url: URL }) {\n  return (\n    <div id=\"root\">\n      <div>\n        <a href=\"https://vite.dev\" target=\"_blank\">\n          <img src={viteLogo} className=\"logo\" alt=\"Vite logo\" />\n        </a>\n        <a href=\"https://react.dev/reference/rsc/server-components\" target=\"_blank\">\n          <img src={reactLogo} className=\"logo react\" alt=\"React logo\" />\n        </a>\n\n        <a href=\"https://nitro.build\" target=\"_blank\">\n          <img src={nitroLogo} className=\"logo\" alt=\"Nitro logo\" />\n        </a>\n      </div>\n      <h1>Vite + RSC + Nitro</h1>\n      <div className=\"card\">\n        <ClientCounter />\n      </div>\n      <div className=\"card\">\n        <form action={updateServerCounter.bind(null, 1)}>\n          <button>Server Counter: {getServerCounter()}</button>\n        </form>\n      </div>\n      <div className=\"card\">Request URL: {props.url?.href}</div>\n      <ul className=\"read-the-docs\">\n        <li>\n          Edit <code>src/client.tsx</code> to test client HMR.\n        </li>\n        <li>\n          Edit <code>src/root.tsx</code> to test server HMR.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"./_.rsc\" target=\"_blank\">\n            <code>_.rsc</code>\n          </a>{\" \"}\n          to view RSC stream payload.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"?__nojs\" target=\"_blank\">\n            <code>?__nojs</code>\n          </a>{\" \"}\n          to test server action without js enabled.\n        </li>\n      </ul>\n    </div>\n  );\n}\n```\n\nServer components run only on the server. They can import CSS directly, use server-side data, and call server actions. The `ClientCounter` component is imported but runs on the client because it has the `\"use client\"` directive.\n\n## 3. Client Component\n\n```tsx [app/client.tsx]\n\"use client\";\n\nimport React from \"react\";\n\nexport function ClientCounter() {\n  const [count, setCount] = React.useState(0);\n\n  return <button onClick={() => setCount((count) => count + 1)}>Client Counter: {count}</button>;\n}\n```\n\nThe `\"use client\"` directive marks this as a client component. It hydrates on the browser and handles interactive state. Server components can import and render client components, but client components cannot import server components.\n\n<!-- /automd -->\n\n## Learn More\n\n- [React Server Components](https://react.dev/reference/rsc/server-components)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-html.md",
    "content": "---\ncategory: server side rendering\nicon: i-logos-html-5\n---\n\n# Vite SSR HTML\n\n> Server-side rendering with vanilla HTML, Vite, and Nitro.\n\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-html\" default=\"app/entry-server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"app/entry-server.ts\" expandAll}\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Nitro Quotes</title>\n    <style>\n      @import \"tailwindcss\";\n    </style>\n  </head>\n  <body\n    class=\"min-h-screen flex items-center justify-center p-5 bg-gradient-to-br from-indigo-500 to-purple-600 font-sans\"\n  >\n    <div class=\"max-w-xl w-full text-center text-white\">\n      <div class=\"bg-white/10 backdrop-blur-md rounded-2xl p-10 shadow-xl border border-white/20\">\n        <div\n          id=\"quote\"\n          class=\"text-[clamp(1.2rem,4vw,1.8rem)] leading-relaxed mb-5 font-light opacity-70 transition-opacity duration-500\"\n        >\n          <!--ssr-outlet-->\n        </div>\n        <div\n          id=\"author\"\n          class=\"text-[clamp(1rem,3vw,1.2rem)] opacity-0 font-normal transition-opacity duration-500\"\n        ></div>\n        <button\n          id=\"refresh-btn\"\n          class=\"mt-5 bg-white/20 border border-white/30 text-white px-6 py-3 rounded-full cursor-pointer text-sm transition hover:bg-white/30 hover:-translate-y-0.5\"\n          onclick=\"fetchQuote()\"\n        >\n          New Quote\n        </button>\n      </div>\n      <div class=\"mt-8 text-sm opacity-60\">\n        Powered by\n        <a\n          class=\"text-white no-underline border-b border-white/30 hover:border-white transition-colors\"\n          href=\"https://vitejs.dev/\"\n          >Vite</a\n        >\n        and\n        <a\n          class=\"text-white no-underline border-b border-white/30 hover:border-white transition-colors\"\n          href=\"https://github.com/nitrojs/nitro\"\n          >Nitro v3</a\n        >.\n      </div>\n    </div>\n\n    <script>\n      const quoteElement = document.getElementById(\"quote\");\n      const authorElement = document.getElementById(\"author\");\n      const refreshBtn = document.getElementById(\"refresh-btn\");\n\n      const baseQuoteClasses =\n        \"text-[clamp(1.2rem,4vw,1.8rem)] leading-relaxed mb-5 font-light transition-opacity duration-500\";\n      const loadingQuoteClasses = baseQuoteClasses + \" opacity-70\";\n      const normalQuoteClasses = baseQuoteClasses + \" opacity-100\";\n      const errorQuoteClasses = baseQuoteClasses + \" text-red-400 opacity-100 text-sm\";\n\n      const baseAuthorClasses =\n        \"text-[clamp(1rem,3vw,1.2rem)] font-normal transition-opacity duration-500\";\n      const hiddenAuthorClasses = baseAuthorClasses + \" opacity-0\";\n      const visibleAuthorClasses = baseAuthorClasses + \" opacity-80\";\n\n      async function fetchQuote() {\n        try {\n          quoteElement.textContent = \"Loading...\";\n          quoteElement.className = loadingQuoteClasses;\n          authorElement.textContent = \"\";\n          authorElement.className = hiddenAuthorClasses;\n          refreshBtn.style.display = \"none\";\n          const response = await fetch(\"/quote\");\n          if (!response.ok) {\n            throw new Error(`HTTP error! status: ${response.status}`);\n          }\n          const { text, author } = await response.json();\n          quoteElement.textContent = `\"${text}\"`;\n          quoteElement.className = normalQuoteClasses;\n          authorElement.textContent = `— ${author}`;\n          authorElement.className = visibleAuthorClasses;\n        } catch (error) {\n          console.error(\"Error fetching quote:\", error);\n          quoteElement.textContent = \"Failed to load quote. Please try again.\";\n          quoteElement.className = errorQuoteClasses;\n          authorElement.textContent = \"\";\n          authorElement.className = hiddenAuthorClasses;\n        } finally {\n          refreshBtn.style.display = \"inline-block\";\n        }\n      }\n    </script>\n  </body>\n</html>\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@tailwindcss/vite\": \"^4.2.2\",\n    \"nitro\": \"latest\",\n    \"tailwindcss\": \"^4.2.2\",\n    \"vite\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro({\n      serverDir: \"./\",\n    }),\n    tailwindcss(),\n  ],\n});\n```\n\n```ts [app/entry-server.ts]\nimport { fetch } from \"nitro\";\n\nexport default {\n  async fetch() {\n    const quote = (await fetch(\"/quote\").then((res) => res.json())) as {\n      text: string;\n    };\n    return tokenizedStream(quote.text, 50);\n  },\n};\n\nfunction tokenizedStream(text: string, delay: number): ReadableStream<Uint8Array> {\n  const tokens = text.split(\" \");\n  return new ReadableStream({\n    start(controller) {\n      let index = 0;\n      function push() {\n        if (index < tokens.length) {\n          const word = tokens[index++] + (index < tokens.length ? \" \" : \"\");\n          controller.enqueue(new TextEncoder().encode(word));\n          setTimeout(push, delay);\n        } else {\n          controller.close();\n        }\n      }\n      push();\n    },\n  });\n}\n```\n\n```ts [routes/quote.ts]\nconst QUOTES_URL =\n  \"https://github.com/JamesFT/Database-Quotes-JSON/raw/refs/heads/master/quotes.json\";\n\nlet _quotes: Promise<unknown> | undefined;\n\nfunction getQuotes() {\n  return (_quotes ??= fetch(QUOTES_URL).then((res) => res.json())) as Promise<\n    { quoteText: string; quoteAuthor: string }[]\n  >;\n}\n\nexport default async function quotesHandler() {\n  const quotes = await getQuotes();\n  const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];\n  return Response.json({\n    text: randomQuote.quoteText,\n    author: randomQuote.quoteAuthor,\n  });\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-html/README.md\" -->\n\nThis example renders an HTML template with server-side data and streams the response word by word. It demonstrates how to use Nitro's Vite SSR integration without a framework.\n\n## Overview\n\n1. **Add the Nitro Vite plugin** to enable SSR\n2. **Create an HTML template** with a `<!--ssr-outlet-->` comment where server content goes\n3. **Create a server entry** that fetches data and returns a stream\n4. **Add API routes** for server-side data\n\n## How It Works\n\nThe `index.html` file contains an `<!--ssr-outlet-->` comment that marks where server-rendered content will be inserted. Nitro replaces this comment with the output from your server entry.\n\nThe server entry exports an object with a `fetch` method. It calls the `/quote` API route using Nitro's internal fetch, then returns a `ReadableStream` that emits the quote text word by word with a 50ms delay between each word.\n\nThe quote route fetches a JSON file of quotes from GitHub, caches the result, and returns a random quote. The server entry calls this route to get content for the page.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Renderer](/docs/renderer)\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-preact.md",
    "content": "---\ncategory: server side rendering\nicon: i-logos-preact\n---\n\n# SSR with Preact\n\n> Server-side rendering with Preact in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-preact\" default=\"src/entry-server.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"src/entry-server.tsx\" expandAll}\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"@preact/preset-vite\": \"^2.10.4\",\n    \"@tailwindcss/vite\": \"^4.2.2\",\n    \"nitro\": \"latest\",\n    \"preact\": \"^10.29.0\",\n    \"preact-render-to-string\": \"^6.6.6\",\n    \"tailwindcss\": \"^4.2.2\",\n    \"vite\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"preact\"\n  }\n}\n```\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport preact from \"@preact/preset-vite\";\n\nexport default defineConfig({\n  plugins: [nitro(), preact()],\n  environments: {\n    client: {\n      build: {\n        rollupOptions: {\n          input: \"./src/entry-client.tsx\",\n        },\n      },\n    },\n  },\n});\n```\n\n```tsx [src/app.tsx]\nimport { useState } from \"preact/hooks\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>;\n}\n```\n\n```tsx [src/entry-client.tsx]\nimport { hydrate } from \"preact\";\nimport { App } from \"./app.tsx\";\n\nfunction main() {\n  hydrate(<App />, document.querySelector(\"#app\")!);\n}\n\nmain();\n```\n\n```tsx [src/entry-server.tsx]\nimport \"./styles.css\";\nimport { renderToReadableStream } from \"preact-render-to-string/stream\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(request: Request) {\n    const url = new URL(request.url);\n    const htmlStream = renderToReadableStream(<Root url={url} />);\n    return new Response(htmlStream, {\n      headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n    });\n  },\n};\n\nfunction Root(props: { url: URL }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n        <script type=\"module\" src={assets.entry} />\n      </head>\n      <body>\n        <h1 className=\"hero\">Nitro + Vite + Preact</h1>\n        <p>URL: {props.url.href}</p>\n        <div id=\"app\">\n          <App />\n        </div>\n      </body>\n    </html>\n  );\n}\n```\n\n```css [src/styles.css]\n.hero {\n  color: orange;\n}\n\nbutton {\n  background-color: lightskyblue;\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-preact/README.md\" -->\n\nSet up server-side rendering (SSR) with Preact, Vite, and Nitro. This setup enables streaming HTML responses, automatic asset management, and client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Configure client and server entry points\n3. Create a server entry that renders your app to HTML\n4. Create a client entry that hydrates the server-rendered HTML\n\n## 1. Configure Vite\n\nAdd the Nitro and Preact plugins to your Vite config. Define the `client` environment with your client entry point:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport preact from \"@preact/preset-vite\";\n\nexport default defineConfig({\n  plugins: [nitro(), preact()],\n  environments: {\n    client: {\n      build: {\n        rollupOptions: {\n          input: \"./src/entry-client.tsx\",\n        },\n      },\n    },\n  },\n});\n```\n\nThe `environments.client` configuration tells Vite which file to use as the browser entry point. Nitro automatically detects the server entry from files named `entry-server` or `server` in common directories.\n\n## 2. Create the App Component\n\nCreate a shared Preact component that runs on both server and client:\n\n```tsx [src/app.tsx]\nimport { useState } from \"preact/hooks\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>;\n}\n```\n\n## 3. Create the Server Entry\n\nThe server entry renders your Preact app to a streaming HTML response using `preact-render-to-string/stream`:\n\n```tsx [src/entry-server.tsx]\nimport \"./styles.css\";\nimport { renderToReadableStream } from \"preact-render-to-string/stream\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(request: Request) {\n    const url = new URL(request.url);\n    const htmlStream = renderToReadableStream(<Root url={url} />);\n    return new Response(htmlStream, {\n      headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n    });\n  },\n};\n\nfunction Root(props: { url: URL }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n        <script type=\"module\" src={assets.entry} />\n      </head>\n      <body>\n        <h1 className=\"hero\">Nitro + Vite + Preact</h1>\n        <p>URL: {props.url.href}</p>\n        <div id=\"app\">\n          <App />\n        </div>\n      </body>\n    </html>\n  );\n}\n```\n\nImport assets using the `?assets=client` and `?assets=ssr` query parameters. Nitro collects CSS and JS assets from each entry point, and `merge()` combines them into a single manifest. The `assets` object provides arrays of stylesheet and script attributes, plus the client entry URL. Use `renderToReadableStream` to stream HTML as Preact renders, improving time-to-first-byte.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML, attaching Preact's event handlers:\n\n```tsx [src/entry-client.tsx]\nimport { hydrate } from \"preact\";\nimport { App } from \"./app.tsx\";\n\nfunction main() {\n  hydrate(<App />, document.querySelector(\"#app\")!);\n}\n\nmain();\n```\n\nThe `hydrate` function attaches Preact to the existing server-rendered DOM inside `#app` without re-rendering it.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Renderer](/docs/renderer)\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-react.md",
    "content": "---\ncategory: server side rendering\nicon: i-logos-react\n---\n\n# SSR with React\n\n> Server-side rendering with React in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-react\" default=\"src/entry-server.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"src/entry-server.tsx\" expandAll}\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"nitro\": \"latest\",\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\",\n    \"react-refresh\": \"^0.18.0\",\n    \"vite\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"react\"\n  }\n}\n```\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n  plugins: [nitro(), react()],\n  environments: {\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n```\n\n```tsx [src/app.tsx]\nimport { useState } from \"react\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return (\n    <>\n      <h1 className=\"hero\">Nitro + Vite + React</h1>\n      <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>\n    </>\n  );\n}\n```\n\n```tsx [src/entry-client.tsx]\nimport \"@vitejs/plugin-react/preamble\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { App } from \"./app.tsx\";\n\nhydrateRoot(document.querySelector(\"#app\")!, <App />);\n```\n\n```tsx [src/entry-server.tsx]\nimport \"./styles.css\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { App } from \"./app.tsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(_req: Request) {\n    const assets = clientAssets.merge(serverAssets);\n    return new Response(\n      await renderToReadableStream(\n        <html lang=\"en\">\n          <head>\n            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n            {assets.css.map((attr: any) => (\n              <link key={attr.href} rel=\"stylesheet\" {...attr} />\n            ))}\n            {assets.js.map((attr: any) => (\n              <link key={attr.href} type=\"modulepreload\" {...attr} />\n            ))}\n            <script type=\"module\" src={assets.entry} />\n          </head>\n          <body id=\"app\">\n            <App />\n          </body>\n        </html>\n      ),\n      { headers: { \"Content-Type\": \"text/html;charset=utf-8\" } }\n    );\n  },\n};\n```\n\n```css [src/styles.css]\n.hero {\n  color: orange;\n}\n\nbutton {\n  background-color: lightskyblue;\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-react/README.md\" -->\n\nSet up server-side rendering (SSR) with React, Vite, and Nitro. This setup enables streaming HTML responses, automatic asset management, and client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Configure client and server entry points\n3. Create a server entry that renders your app to HTML\n4. Create a client entry that hydrates the server-rendered HTML\n\n## 1. Configure Vite\n\nAdd the Nitro and React plugins to your Vite config. Define the `client` environment with your client entry point:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n  plugins: [nitro(), react()],\n  environments: {\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n```\n\nThe `environments.client` configuration tells Vite which file to use as the browser entry point. Nitro automatically detects the server entry from files named `entry-server` or `server` in common directories.\n\n## 2. Create the App Component\n\nCreate a shared React component that runs on both server and client:\n\n```tsx [src/app.tsx]\nimport { useState } from \"react\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return (\n    <>\n      <h1 className=\"hero\">Nitro + Vite + React</h1>\n      <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>\n    </>\n  );\n}\n```\n\n## 3. Create the Server Entry\n\nThe server entry renders your React app to a streaming HTML response. It uses `react-dom/server.edge` for edge-compatible streaming:\n\n```tsx [src/entry-server.tsx]\nimport \"./styles.css\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { App } from \"./app.tsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(_req: Request) {\n    const assets = clientAssets.merge(serverAssets);\n    return new Response(\n      await renderToReadableStream(\n        <html lang=\"en\">\n          <head>\n            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n            {assets.css.map((attr: any) => (\n              <link key={attr.href} rel=\"stylesheet\" {...attr} />\n            ))}\n            {assets.js.map((attr: any) => (\n              <link key={attr.href} type=\"modulepreload\" {...attr} />\n            ))}\n            <script type=\"module\" src={assets.entry} />\n          </head>\n          <body id=\"app\">\n            <App />\n          </body>\n        </html>\n      ),\n      { headers: { \"Content-Type\": \"text/html;charset=utf-8\" } }\n    );\n  },\n};\n```\n\nImport assets using the `?assets=client` and `?assets=ssr` query parameters. Nitro collects CSS and JS assets from each entry point, and `merge()` combines them into a single manifest. The `assets` object provides arrays of stylesheet and script attributes, plus the client entry URL. Use `renderToReadableStream` to stream HTML as React renders, improving time-to-first-byte.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML, attaching React's event handlers:\n\n```tsx [src/entry-client.tsx]\nimport \"@vitejs/plugin-react/preamble\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { App } from \"./app.tsx\";\n\nhydrateRoot(document.querySelector(\"#app\")!, <App />);\n```\n\nThe `@vitejs/plugin-react/preamble` import is required for React Fast Refresh during development. The `hydrateRoot` function attaches React to the existing server-rendered DOM without re-rendering it.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Renderer](/docs/renderer)\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-solid.md",
    "content": "---\ncategory: server side rendering\nicon: i-logos-solidjs-icon\n---\n\n# SSR with SolidJS\n\n> Server-side rendering with SolidJS in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-solid\" default=\"src/entry-server.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"src/entry-server.tsx\" expandAll}\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"solid-js\": \"^1.9.11\",\n    \"vite\": \"latest\",\n    \"vite-plugin-solid\": \"^2.11.11\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"preserve\",\n    \"jsxImportSource\": \"solid-js\"\n  }\n}\n```\n\n```js [vite.config.mjs]\nimport solid from \"vite-plugin-solid\";\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [solid({ ssr: true }), nitro()],\n  esbuild: { jsx: \"preserve\", jsxImportSource: \"solid-js\" },\n  environments: {\n    ssr: {\n      build: { rollupOptions: { input: \"./src/entry-server.tsx\" } },\n    },\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n```\n\n```tsx [src/app.tsx]\nimport { createSignal } from \"solid-js\";\n\nexport function App() {\n  const [count, setCount] = createSignal(0);\n\n  return (\n    <div>\n      <h1>Hello, Solid!</h1>\n      <button onClick={() => setCount((count) => count + 1)}>Count: {count()}</button>\n    </div>\n  );\n}\n```\n\n```tsx [src/entry-client.tsx]\nimport { hydrate } from \"solid-js/web\";\nimport \"./styles.css\";\nimport { App } from \"./app.jsx\";\n\nhydrate(() => <App />, document.querySelector(\"#app\")!);\n```\n\n```tsx [src/entry-server.tsx]\nimport { renderToStringAsync, HydrationScript } from \"solid-js/web\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(req: Request): Promise<Response> {\n    const appHTML = await renderToStringAsync(() => <App />);\n    const rootHTML = await renderToStringAsync(() => <Root appHTML={appHTML} />);\n    return new Response(rootHTML, {\n      headers: { \"Content-Type\": \"text/html\" },\n    });\n  },\n};\n\nfunction Root(props: { appHTML?: string }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n      </head>\n      <body>\n        <div id=\"app\" innerHTML={props.appHTML || \"\"} />\n        <HydrationScript />\n        <script type=\"module\" src={assets.entry} />\n      </body>\n    </html>\n  );\n}\n```\n\n```css [src/styles.css]\ndiv {\n  font-family: system-ui, Arial, sans-serif;\n  font-size: 20px;\n  margin-bottom: 10px;\n}\n\nbutton {\n  background-color: rgb(147 197 253);\n  color: rgb(15 23 42);\n  border: none;\n  padding: 10px 20px;\n  font-size: 16px;\n  cursor: pointer;\n  border-radius: 5px;\n}\n\nbutton:hover {\n  background-color: rgb(191 219 254);\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-solid/README.md\" -->\n\nSet up server-side rendering (SSR) with SolidJS, Vite, and Nitro. This setup uses `renderToStringAsync` for HTML generation and supports client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Configure client and server entry points\n3. Create a server entry that renders your app to HTML\n4. Create a client entry that hydrates the server-rendered HTML\n\n## 1. Configure Vite\n\nAdd the Nitro and SolidJS plugins to your Vite config. SolidJS requires explicit JSX configuration and both `ssr` and `client` environments:\n\n```js [vite.config.mjs]\nimport solid from \"vite-plugin-solid\";\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [solid({ ssr: true }), nitro()],\n  esbuild: { jsx: \"preserve\", jsxImportSource: \"solid-js\" },\n  environments: {\n    ssr: {\n      build: { rollupOptions: { input: \"./src/entry-server.tsx\" } },\n    },\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n```\n\nEnable SSR mode in the Solid plugin with `solid({ ssr: true })`. Configure esbuild to preserve JSX for Solid's compiler and use Solid's JSX runtime. SolidJS requires explicit `ssr` and `client` environment configuration in Vite.\n\n## 2. Create the App Component\n\nCreate a shared SolidJS component using reactive signals:\n\n```tsx [src/app.tsx]\nimport { createSignal } from \"solid-js\";\n\nexport function App() {\n  const [count, setCount] = createSignal(0);\n\n  return (\n    <div>\n      <h1>Hello, Solid!</h1>\n      <button onClick={() => setCount((count) => count + 1)}>Count: {count()}</button>\n    </div>\n  );\n}\n```\n\nSolidJS uses signals (`createSignal`) for state management. Unlike React's `useState`, signals are getter functions that you call to read the value.\n\n## 3. Create the Server Entry\n\nThe server entry renders your SolidJS app to HTML using `renderToStringAsync` and includes the `HydrationScript` for client-side hydration:\n\n```tsx [src/entry-server.tsx]\nimport { renderToStringAsync, HydrationScript } from \"solid-js/web\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(req: Request): Promise<Response> {\n    const appHTML = await renderToStringAsync(() => <App />);\n    const rootHTML = await renderToStringAsync(() => <Root appHTML={appHTML} />);\n    return new Response(rootHTML, {\n      headers: { \"Content-Type\": \"text/html\" },\n    });\n  },\n};\n\nfunction Root(props: { appHTML?: string }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n      </head>\n      <body>\n        <div id=\"app\" innerHTML={props.appHTML || \"\"} />\n        <HydrationScript />\n        <script type=\"module\" src={assets.entry} />\n      </body>\n    </html>\n  );\n}\n```\n\nSolidJS requires rendering the app separately from the shell (two-phase rendering). The app HTML is injected via `innerHTML` to preserve hydration markers. Include the `HydrationScript` component to inject the script Solid needs to rehydrate on the client. Import assets using the `?assets=client` and `?assets=ssr` query parameters to collect CSS and JS from each entry point.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML, restoring Solid's reactivity:\n\n```tsx [src/entry-client.tsx]\nimport { hydrate } from \"solid-js/web\";\nimport \"./styles.css\";\nimport { App } from \"./app.jsx\";\n\nhydrate(() => <App />, document.querySelector(\"#app\")!);\n```\n\nThe `hydrate` function attaches Solid's reactive system to the existing server-rendered DOM inside `#app`. The component is wrapped in a function `() => <App />` as required by Solid's API.\n\n<!-- /automd -->\n\n## Learn More\n\n- [SolidJS Documentation](https://docs.solidjs.com/)\n- [Renderer](/docs/renderer)\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-tsr-react.md",
    "content": "---\ncategory: server side rendering\nicon: i-simple-icons-tanstack\n---\n\n# SSR with TanStack Router\n\n> Client-side routing with TanStack Router in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-tsr-react\" default=\"src/main.tsx\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"src/main.tsx\" expandAll}\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Nitro + TanStack Router + React</title>\n  </head>\n\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@tanstack/react-router\": \"^1.168.1\",\n    \"@tanstack/react-router-devtools\": \"^1.166.10\",\n    \"@tanstack/router-plugin\": \"^1.167.1\",\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"nitro\": \"latest\",\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\",\n    \"vite\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"jsx\": \"react-jsx\",\n    \"paths\": {\n      \"@/*\": [\"sec/*\"]\n    }\n  }\n}\n```\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\n\nexport default defineConfig({\n  plugins: [tanstackRouter({ target: \"react\", autoCodeSplitting: true }), react(), nitro()],\n});\n```\n\n```tsx [src/main.tsx]\nimport { StrictMode } from \"react\";\nimport ReactDOM from \"react-dom/client\";\nimport { RouterProvider, createRouter } from \"@tanstack/react-router\";\n\n// Import the generated route tree\nimport { routeTree } from \"./routeTree.gen.ts\";\n\n// Create a new router instance\nconst router = createRouter({ routeTree });\n\n// Register the router instance for type safety\ndeclare module \"@tanstack/react-router\" {\n  interface Register {\n    router: typeof router;\n  }\n}\n\n// Render the app\nconst rootElement = document.querySelector(\"#root\")!;\nif (!rootElement.innerHTML) {\n  const root = ReactDOM.createRoot(rootElement);\n  root.render(\n    <StrictMode>\n      <RouterProvider router={router} />\n    </StrictMode>\n  );\n}\n```\n\n```ts [src/routeTree.gen.ts]\n/* eslint-disable */\n\n// @ts-nocheck\n\n// noinspection JSUnusedGlobalSymbols\n\n// This file was automatically generated by TanStack Router.\n// You should NOT make any changes in this file as it will be overwritten.\n// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.\n\nimport { Route as rootRouteImport } from './routes/__root'\nimport { Route as IndexRouteImport } from './routes/index'\n\nconst IndexRoute = IndexRouteImport.update({\n  id: '/',\n  path: '/',\n  getParentRoute: () => rootRouteImport,\n} as any)\n\nexport interface FileRoutesByFullPath {\n  '/': typeof IndexRoute\n}\nexport interface FileRoutesByTo {\n  '/': typeof IndexRoute\n}\nexport interface FileRoutesById {\n  __root__: typeof rootRouteImport\n  '/': typeof IndexRoute\n}\nexport interface FileRouteTypes {\n  fileRoutesByFullPath: FileRoutesByFullPath\n  fullPaths: '/'\n  fileRoutesByTo: FileRoutesByTo\n  to: '/'\n  id: '__root__' | '/'\n  fileRoutesById: FileRoutesById\n}\nexport interface RootRouteChildren {\n  IndexRoute: typeof IndexRoute\n}\n\ndeclare module '@tanstack/react-router' {\n  interface FileRoutesByPath {\n    '/': {\n      id: '/'\n      path: '/'\n      fullPath: '/'\n      preLoaderRoute: typeof IndexRouteImport\n      parentRoute: typeof rootRouteImport\n    }\n  }\n}\n\nconst rootRouteChildren: RootRouteChildren = {\n  IndexRoute: IndexRoute,\n}\nexport const routeTree = rootRouteImport\n  ._addFileChildren(rootRouteChildren)\n  ._addFileTypes<FileRouteTypes>()\n```\n\n```css [src/assets/main.css]\n:root {\n  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;\n  line-height: 1.5;\n  font-weight: 400;\n\n  color-scheme: light dark;\n  color: rgba(255, 255, 255, 0.87);\n  background-color: #242424;\n\n  font-synthesis: none;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\na {\n  font-weight: 500;\n  color: #ff2056;\n  text-decoration: inherit;\n}\na:hover {\n  color: #ff637e;\n}\n\nbody {\n  margin: 0;\n  display: flex;\n  flex-direction: column;\n  place-items: center;\n  justify-content: center;\n  min-width: 320px;\n  min-height: 100vh;\n}\n\nh1 {\n  font-size: 3.2em;\n  line-height: 1.1;\n}\n\n#app {\n  max-width: 1280px;\n  margin: 0 auto;\n  padding: 2rem;\n  text-align: center;\n}\n\n.logo {\n  height: 6em;\n  padding: 1.5em;\n  will-change: filter;\n  transition: filter 300ms;\n  transition: transform 300ms;\n}\n.logo:hover {\n  transform: scale(1.1);\n}\n\n.card {\n  padding: 2em;\n}\n\n.read-the-docs {\n  color: #888;\n}\n\nbutton {\n  border-radius: 8px;\n  border: 1px solid transparent;\n  padding: 0.6em 1.2em;\n  font-size: 1em;\n  font-weight: 500;\n  font-family: inherit;\n  background-color: #1a1a1a;\n  cursor: pointer;\n  transition: border-color 0.25s;\n}\nbutton:hover {\n  border-color: #646cff;\n}\nbutton:focus,\nbutton:focus-visible {\n  outline: 4px auto -webkit-focus-ring-color;\n}\n\n@media (prefers-color-scheme: light) {\n  :root {\n    color: #213547;\n    background-color: #ffffff;\n  }\n  a:hover {\n    color: #747bff;\n  }\n  button {\n    background-color: #f9f9f9;\n  }\n}\n```\n\n```tsx [src/routes/__root.tsx]\nimport { createRootRoute, Link, Outlet } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\n\nconst RootLayout = () => (\n  <>\n    <div className=\"p-2 flex gap-2\">\n      <Link to=\"/\" className=\"[&.active]:font-bold\">\n        Home\n      </Link>\n    </div>\n    <hr />\n    <Outlet />\n    <TanStackRouterDevtools />\n  </>\n);\n\nexport const Route = createRootRoute({ component: RootLayout });\n```\n\n```tsx [src/routes/index.tsx]\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({\n  loader: async () => {\n    const r = await fetch(\"/api/hello\");\n    return r.json();\n  },\n  component: Index,\n});\n\nfunction Index() {\n  const r = Route.useLoaderData();\n\n  return (\n    <div className=\"p-2\">\n      <h3>{JSON.stringify(r)}</h3>\n    </div>\n  );\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-tsr-react/README.md\" -->\n\nSet up TanStack Router with React, Vite, and Nitro. This setup provides file-based routing with type-safe navigation and automatic code splitting.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Create an HTML template with your app entry\n3. Create a main entry that initializes the router\n4. Define routes using file-based routing\n\n## 1. Configure Vite\n\nAdd the Nitro, React, and TanStack Router plugins to your Vite config:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\n\nexport default defineConfig({\n  plugins: [tanstackRouter({ target: \"react\", autoCodeSplitting: true }), react(), nitro()],\n});\n```\n\nThe `tanstackRouter` plugin generates a route tree from your `routes/` directory structure. Enable `autoCodeSplitting` to automatically split routes into separate chunks. Place the TanStack Router plugin before the React plugin in the array.\n\n## 2. Create the HTML Template\n\nCreate an HTML file that serves as your app shell:\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Nitro + TanStack Router + React</title>\n  </head>\n\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n```\n\n## 3. Create the App Entry\n\nCreate the main entry that initializes TanStack Router:\n\n```tsx [src/main.tsx]\nimport { StrictMode } from \"react\";\nimport ReactDOM from \"react-dom/client\";\nimport { RouterProvider, createRouter } from \"@tanstack/react-router\";\n\n// Import the generated route tree\nimport { routeTree } from \"./routeTree.gen.ts\";\n\n// Create a new router instance\nconst router = createRouter({ routeTree });\n\n// Register the router instance for type safety\ndeclare module \"@tanstack/react-router\" {\n  interface Register {\n    router: typeof router;\n  }\n}\n\n// Render the app\nconst rootElement = document.querySelector(\"#root\")!;\nif (!rootElement.innerHTML) {\n  const root = ReactDOM.createRoot(rootElement);\n  root.render(\n    <StrictMode>\n      <RouterProvider router={router} />\n    </StrictMode>\n  );\n}\n```\n\nThe `routeTree.gen.ts` file is auto-generated from your `routes/` directory structure. The `Register` interface declaration provides full type inference for route paths and params. The `!rootElement.innerHTML` check prevents re-rendering during hot module replacement.\n\n## 4. Create the Root Route\n\nThe root route (`__root.tsx`) defines your app's layout:\n\n```tsx [src/routes/__root.tsx]\nimport { createRootRoute, Link, Outlet } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\n\nconst RootLayout = () => (\n  <>\n    <div className=\"p-2 flex gap-2\">\n      <Link to=\"/\" className=\"[&.active]:font-bold\">\n        Home\n      </Link>\n    </div>\n    <hr />\n    <Outlet />\n    <TanStackRouterDevtools />\n  </>\n);\n\nexport const Route = createRootRoute({ component: RootLayout });\n```\n\nUse `Link` for type-safe navigation with active state styling. The `Outlet` component renders child routes. Include `TanStackRouterDevtools` for development tools (automatically removed in production).\n\n## 5. Create Page Routes\n\nPage routes use `createFileRoute` and can include loaders:\n\n```tsx [src/routes/index.tsx]\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({\n  loader: async () => {\n    const r = await fetch(\"/api/hello\");\n    return r.json();\n  },\n  component: Index,\n});\n\nfunction Index() {\n  const r = Route.useLoaderData();\n\n  return (\n    <div className=\"p-2\">\n      <h3>{JSON.stringify(r)}</h3>\n    </div>\n  );\n}\n```\n\nFetch data before rendering with the `loader` function—data is available via `Route.useLoaderData()`. File paths determine URL paths: `routes/index.tsx` maps to `/`, `routes/about.tsx` to `/about`, and `routes/users/$id.tsx` to `/users/:id`.\n\n<!-- /automd -->\n\n## Learn More\n\n- [TanStack Router Documentation](https://tanstack.com/router)\n- [Renderer](/docs/renderer)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-tss-react.md",
    "content": "---\ncategory: server side rendering\nicon: i-simple-icons-tanstack\n---\n\n# SSR with TanStack Start\n\n> Full-stack React with TanStack Start in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-tss-react\" default=\"server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server.ts\" expandAll}\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"start\": \"node .output/server/index.mjs\"\n  },\n  \"dependencies\": {\n    \"@tanstack/react-router\": \"^1.168.1\",\n    \"@tanstack/react-router-devtools\": \"^1.166.10\",\n    \"@tanstack/react-start\": \"^1.167.1\",\n    \"nitro\": \"latest\",\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\",\n    \"tailwind-merge\": \"^3.5.0\",\n    \"zod\": \"^4.3.6\"\n  },\n  \"devDependencies\": {\n    \"@tailwindcss/vite\": \"^4.2.2\",\n    \"@types/node\": \"latest\",\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"tailwindcss\": \"^4.2.2\",\n    \"typescript\": \"^5.9.3\",\n    \"vite\": \"latest\",\n    \"vite-tsconfig-paths\": \"^6.1.1\"\n  }\n}\n```\n\n```ts [server.ts]\nimport handler, { createServerEntry } from \"@tanstack/react-start/server-entry\";\n\nexport default createServerEntry({\n  fetch(request) {\n    return handler.fetch(request);\n  },\n});\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"jsx\": \"react-jsx\",\n    \"paths\": {\n      \"~/*\": [\"./src/*\"]\n    }\n  }\n}\n```\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport { tanstackStart } from \"@tanstack/react-start/plugin/vite\";\nimport viteReact from \"@vitejs/plugin-react\";\nimport viteTsConfigPaths from \"vite-tsconfig-paths\";\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  plugins: [\n    viteTsConfigPaths({ projects: [\"./tsconfig.json\"] }),\n    tanstackStart(),\n    viteReact(),\n    tailwindcss(),\n    nitro(),\n  ],\n  environments: {\n    ssr: { build: { rollupOptions: { input: \"./server.ts\" } } },\n  },\n});\n```\n\n```tsx [src/router.tsx]\nimport { createRouter } from \"@tanstack/react-router\";\nimport { routeTree } from \"./routeTree.gen.ts\";\n\nexport function getRouter() {\n  const router = createRouter({\n    routeTree,\n    defaultPreload: \"intent\",\n    defaultErrorComponent: () => <div>Internal Server Error</div>,\n    defaultNotFoundComponent: () => <div>Not Found</div>,\n    scrollRestoration: true,\n  });\n  return router;\n}\n```\n\n```ts [src/routeTree.gen.ts]\n/* eslint-disable */\n\n// @ts-nocheck\n\n// noinspection JSUnusedGlobalSymbols\n\n// This file was automatically generated by TanStack Router.\n// You should NOT make any changes in this file as it will be overwritten.\n// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.\n\nimport { Route as rootRouteImport } from './routes/__root'\nimport { Route as IndexRouteImport } from './routes/index'\nimport { Route as ApiTestRouteImport } from './routes/api/test'\n\nconst IndexRoute = IndexRouteImport.update({\n  id: '/',\n  path: '/',\n  getParentRoute: () => rootRouteImport,\n} as any)\nconst ApiTestRoute = ApiTestRouteImport.update({\n  id: '/api/test',\n  path: '/api/test',\n  getParentRoute: () => rootRouteImport,\n} as any)\n\nexport interface FileRoutesByFullPath {\n  '/': typeof IndexRoute\n  '/api/test': typeof ApiTestRoute\n}\nexport interface FileRoutesByTo {\n  '/': typeof IndexRoute\n  '/api/test': typeof ApiTestRoute\n}\nexport interface FileRoutesById {\n  __root__: typeof rootRouteImport\n  '/': typeof IndexRoute\n  '/api/test': typeof ApiTestRoute\n}\nexport interface FileRouteTypes {\n  fileRoutesByFullPath: FileRoutesByFullPath\n  fullPaths: '/' | '/api/test'\n  fileRoutesByTo: FileRoutesByTo\n  to: '/' | '/api/test'\n  id: '__root__' | '/' | '/api/test'\n  fileRoutesById: FileRoutesById\n}\nexport interface RootRouteChildren {\n  IndexRoute: typeof IndexRoute\n  ApiTestRoute: typeof ApiTestRoute\n}\n\ndeclare module '@tanstack/react-router' {\n  interface FileRoutesByPath {\n    '/': {\n      id: '/'\n      path: '/'\n      fullPath: '/'\n      preLoaderRoute: typeof IndexRouteImport\n      parentRoute: typeof rootRouteImport\n    }\n    '/api/test': {\n      id: '/api/test'\n      path: '/api/test'\n      fullPath: '/api/test'\n      preLoaderRoute: typeof ApiTestRouteImport\n      parentRoute: typeof rootRouteImport\n    }\n  }\n}\n\nconst rootRouteChildren: RootRouteChildren = {\n  IndexRoute: IndexRoute,\n  ApiTestRoute: ApiTestRoute,\n}\nexport const routeTree = rootRouteImport\n  ._addFileChildren(rootRouteChildren)\n  ._addFileTypes<FileRouteTypes>()\n\nimport type { getRouter } from './router.tsx'\nimport type { createStart } from '@tanstack/react-start'\ndeclare module '@tanstack/react-start' {\n  interface Register {\n    ssr: true\n    router: Awaited<ReturnType<typeof getRouter>>\n  }\n}\n```\n\n```tsx [src/routes/__root.tsx]\n/// <reference types=\"vite/client\" />\nimport { HeadContent, Link, Scripts, createRootRoute } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\nimport * as React from \"react\";\nimport appCss from \"~/styles/app.css?url\";\n\nexport const Route = createRootRoute({\n  head: () => ({\n    meta: [\n      { charSet: \"utf8\" },\n      { name: \"viewport\", content: \"width=device-width, initial-scale=1\" },\n    ],\n    links: [{ rel: \"stylesheet\", href: appCss }],\n    scripts: [{ src: \"/customScript.js\", type: \"text/javascript\" }],\n  }),\n  errorComponent: () => <h1>500: Internal Server Error</h1>,\n  notFoundComponent: () => <h1>404: Page Not Found</h1>,\n  shellComponent: RootDocument,\n});\n\nfunction RootDocument({ children }: { children: React.ReactNode }) {\n  return (\n    <html>\n      <head>\n        <HeadContent />\n      </head>\n      <body>\n        <div className=\"p-2 flex gap-2 text-lg\">\n          <Link to=\"/\" activeProps={{ className: \"font-bold\" }} activeOptions={{ exact: true }}>\n            Home\n          </Link>{\" \"}\n          <Link\n            // @ts-ignore\n            to=\"/this-route-does-not-exist\"\n            activeProps={{ className: \"font-bold\" }}\n          >\n            404\n          </Link>\n        </div>\n        <hr />\n        {children}\n        <TanStackRouterDevtools position=\"bottom-right\" />\n        <Scripts />\n      </body>\n    </html>\n  );\n}\n```\n\n```tsx [src/routes/index.tsx]\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({ component: Home });\n\nfunction Home() {\n  return (\n    <div className=\"p-2\">\n      <h3>Welcome Home!</h3>\n      <a href=\"/api/test\">/api/test</a>\n    </div>\n  );\n}\n```\n\n```css [src/styles/app.css]\n@import \"tailwindcss\";\n\n@layer base {\n  *,\n  ::after,\n  ::before,\n  ::backdrop,\n  ::file-selector-button {\n    border-color: var(--color-gray-200, currentcolor);\n  }\n}\n\n@layer base {\n  html {\n    color-scheme: light dark;\n  }\n\n  * {\n    @apply border-gray-200 dark:border-gray-800;\n  }\n\n  html,\n  body {\n    @apply text-gray-900 bg-gray-50 dark:bg-gray-950 dark:text-gray-200;\n  }\n\n  .using-mouse * {\n    outline: none !important;\n  }\n}\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-tss-react/README.md\" -->\n\nSet up TanStack Start with Nitro for a full-stack React framework experience with server-side rendering, file-based routing, and integrated API routes.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Create a server entry using TanStack Start's server handler\n3. Configure the router with default components\n4. Define routes and API endpoints using file-based routing\n\n## 1. Configure Vite\n\nAdd the Nitro, React, TanStack Start, and Tailwind plugins to your Vite config:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport { tanstackStart } from \"@tanstack/react-start/plugin/vite\";\nimport viteReact from \"@vitejs/plugin-react\";\nimport viteTsConfigPaths from \"vite-tsconfig-paths\";\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  plugins: [\n    viteTsConfigPaths({ projects: [\"./tsconfig.json\"] }),\n    tanstackStart(),\n    viteReact(),\n    tailwindcss(),\n    nitro(),\n  ],\n  environments: {\n    ssr: { build: { rollupOptions: { input: \"./server.ts\" } } },\n  },\n});\n```\n\nThe `tanstackStart()` plugin provides full SSR integration with automatic client entry handling. Use `viteTsConfigPaths()` to enable path aliases like `~/` from tsconfig. The `environments.ssr` option points to the server entry file.\n\n## 2. Create the Server Entry\n\nCreate a server entry that uses TanStack Start's handler:\n\n```ts [server.ts]\nimport handler, { createServerEntry } from \"@tanstack/react-start/server-entry\";\n\nexport default createServerEntry({\n  fetch(request) {\n    return handler.fetch(request);\n  },\n});\n```\n\nTanStack Start handles SSR automatically. The `createServerEntry` wrapper integrates with Nitro's server entry format, and the `handler.fetch` processes all incoming requests.\n\n## 3. Configure the Router\n\nCreate a router factory function with default error and not-found components:\n\n```tsx [src/router.tsx]\nimport { createRouter } from \"@tanstack/react-router\";\nimport { routeTree } from \"./routeTree.gen.ts\";\n\nexport function getRouter() {\n  const router = createRouter({\n    routeTree,\n    defaultPreload: \"intent\",\n    defaultErrorComponent: () => <div>Internal Server Error</div>,\n    defaultNotFoundComponent: () => <div>Not Found</div>,\n    scrollRestoration: true,\n  });\n  return router;\n}\n```\n\nThe router factory configures preloading behavior, scroll restoration, and default error/not-found components.\n\n## 4. Create the Root Route\n\nThe root route defines your HTML shell with head management and scripts:\n\n```tsx [src/routes/__root.tsx]\n/// <reference types=\"vite/client\" />\nimport { HeadContent, Link, Scripts, createRootRoute } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\nimport * as React from \"react\";\nimport appCss from \"~/styles/app.css?url\";\n\nexport const Route = createRootRoute({\n  head: () => ({\n    meta: [\n      { charSet: \"utf8\" },\n      { name: \"viewport\", content: \"width=device-width, initial-scale=1\" },\n    ],\n    links: [{ rel: \"stylesheet\", href: appCss }],\n    scripts: [{ src: \"/customScript.js\", type: \"text/javascript\" }],\n  }),\n  errorComponent: () => <h1>500: Internal Server Error</h1>,\n  notFoundComponent: () => <h1>404: Page Not Found</h1>,\n  shellComponent: RootDocument,\n});\n\nfunction RootDocument({ children }: { children: React.ReactNode }) {\n  return (\n    <html>\n      <head>\n        <HeadContent />\n      </head>\n      <body>\n        <div className=\"p-2 flex gap-2 text-lg\">\n          <Link to=\"/\" activeProps={{ className: \"font-bold\" }} activeOptions={{ exact: true }}>\n            Home\n          </Link>{\" \"}\n          <Link\n            // @ts-ignore\n            to=\"/this-route-does-not-exist\"\n            activeProps={{ className: \"font-bold\" }}\n          >\n            404\n          </Link>\n        </div>\n        <hr />\n        {children}\n        <TanStackRouterDevtools position=\"bottom-right\" />\n        <Scripts />\n      </body>\n    </html>\n  );\n}\n```\n\nDefine meta tags, stylesheets, and scripts in the `head()` function. The `shellComponent` provides the HTML document shell that wraps all pages. Use `HeadContent` to render the head configuration and `Scripts` to inject the client-side JavaScript for hydration.\n\n## 5. Create Page Routes\n\nPage routes define your application pages:\n\n```tsx [src/routes/index.tsx]\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({ component: Home });\n\nfunction Home() {\n  return (\n    <div className=\"p-2\">\n      <h3>Welcome Home!</h3>\n      <a href=\"/api/test\">/api/test</a>\n    </div>\n  );\n}\n```\n\n## API Routes\n\nTanStack Start supports API routes alongside page routes. Create files in `src/routes/api/` to define server endpoints that Nitro serves automatically.\n\n<!-- /automd -->\n\n## Learn More\n\n- [TanStack Start Documentation](https://tanstack.com/start)\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/vite-ssr-vue-router.md",
    "content": "---\ncategory: server side rendering\nicon: i-logos-vue\n---\n\n# SSR with Vue Router\n\n> Server-side rendering with Vue Router in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-ssr-vue-router\" default=\"app/entry-server.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"app/entry-server.ts\" expandAll}\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@vitejs/plugin-vue\": \"^6.0.5\",\n    \"nitro\": \"latest\",\n    \"unhead\": \"^2.1.12\",\n    \"vite\": \"latest\",\n    \"vite-plugin-devtools-json\": \"^1.0.0\",\n    \"vue\": \"^3.5.30\",\n    \"vue-router\": \"^4.6.4\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```js [vite.config.mjs]\nimport vue from \"@vitejs/plugin-vue\";\nimport { defineConfig } from \"vite\";\nimport devtoolsJson from \"vite-plugin-devtools-json\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig((_env) => ({\n  plugins: [patchVueExclude(vue(), /\\?assets/), devtoolsJson(), nitro()],\n  environments: {\n    client: { build: { rollupOptions: { input: \"./app/entry-client.ts\" } } },\n    ssr: { build: { rollupOptions: { input: \"./app/entry-server.ts\" } } },\n  },\n}));\n\n// Workaround https://github.com/vitejs/vite-plugin-vue/issues/677\nfunction patchVueExclude(plugin, exclude) {\n  const original = plugin.transform.handler;\n  plugin.transform.handler = function (...args) {\n    if (exclude.test(args[1])) return;\n    return original.call(this, ...args);\n  };\n  return plugin;\n}\n```\n\n```vue [app/app.vue]\n<script setup lang=\"ts\">\nimport { RouterLink, RouterView } from \"vue-router\";\nimport \"./styles.css\";\n</script>\n\n<template>\n  <nav>\n    <ul>\n      <li>\n        <RouterLink to=\"/\" exact-active-class=\"active\">Home</RouterLink>\n      </li>\n      <li>\n        <RouterLink to=\"/about\" active-class=\"active\">About</RouterLink>\n      </li>\n    </ul>\n  </nav>\n  <RouterView />\n</template>\n\n<style scoped>\nnav {\n  background: white;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  padding: 1rem;\n}\n\nnav ul {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  display: flex;\n  gap: 2rem;\n  max-width: 800px;\n  margin: 0 auto;\n}\n\nnav a {\n  color: #666;\n  text-decoration: none;\n}\n\nnav a:hover {\n  color: #333;\n}\n\nnav a.active {\n  color: #646cff;\n}\n</style>\n```\n\n```ts [app/entry-client.ts]\nimport { createSSRApp } from \"vue\";\nimport { RouterView, createRouter, createWebHistory } from \"vue-router\";\nimport { routes } from \"./routes.ts\";\n\nasync function main() {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createWebHistory(), routes });\n  app.use(router);\n\n  await router.isReady();\n  app.mount(\"#root\");\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain();\n```\n\n```ts [app/entry-server.ts]\nimport { createSSRApp } from \"vue\";\nimport { renderToString } from \"vue/server-renderer\";\nimport { RouterView, createMemoryHistory, createRouter } from \"vue-router\";\nimport { createHead, transformHtmlTemplate } from \"unhead/server\";\n\nimport { routes } from \"./routes.ts\";\n\nimport clientAssets from \"./entry-client.ts?assets=client\";\n\nasync function handler(request: Request): Promise<Response> {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createMemoryHistory(), routes });\n  app.use(router);\n\n  const url = new URL(request.url);\n  const href = url.href.slice(url.origin.length);\n\n  await router.push(href);\n  await router.isReady();\n\n  const assets = clientAssets.merge(\n    ...(await Promise.all(\n      router.currentRoute.value.matched\n        .map((to) => to.meta.assets)\n        .filter(Boolean)\n        .map((fn) => (fn as any)().then((m: any) => m.default))\n    ))\n  );\n\n  const head = createHead();\n\n  head.push({\n    link: [\n      ...assets.css.map((attrs: any) => ({ rel: \"stylesheet\", ...attrs })),\n      ...assets.js.map((attrs: any) => ({ rel: \"modulepreload\", ...attrs })),\n    ],\n    script: [{ type: \"module\", src: clientAssets.entry }],\n  });\n\n  const renderedApp = await renderToString(app);\n\n  const html = await transformHtmlTemplate(head, htmlTemplate(renderedApp));\n\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n  });\n}\n\nfunction htmlTemplate(body: string): string {\n  return /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>Vue Router Custom Framework</title>\n</head>\n<body>\n  <div id=\"root\">${body}</div>\n</body>\n</html>`;\n}\n\nexport default {\n  fetch: handler,\n};\n```\n\n```ts [app/routes.ts]\nimport type { RouteRecordRaw } from \"vue-router\";\n\nexport const routes: RouteRecordRaw[] = [\n  {\n    path: \"/\",\n    name: \"app\",\n    component: () => import(\"./app.vue\"),\n    meta: {\n      assets: () => import(\"./app.vue?assets\"),\n    },\n    children: [\n      {\n        path: \"/\",\n        name: \"home\",\n        component: () => import(\"./pages/index.vue\"),\n        meta: {\n          assets: () => import(\"./pages/index.vue?assets\"),\n        },\n      },\n      {\n        path: \"/about\",\n        name: \"about\",\n        component: () => import(\"./pages/about.vue\"),\n        meta: {\n          assets: () => import(\"./pages/about.vue?assets\"),\n        },\n      },\n      {\n        path: \"/:catchAll(.*)\",\n        name: \"not-found\",\n        component: () => import(\"./pages/not-found.vue\"),\n        meta: {\n          assets: () => import(\"./pages/not-found.vue?assets\"),\n        },\n      },\n    ],\n  },\n];\n```\n\n```ts [app/shims.d.ts]\ndeclare module \"*.vue\" {\n  import type { DefineComponent } from \"vue\";\n  const component: DefineComponent<{}, {}, any>;\n  export default component;\n}\n```\n\n```css [app/styles.css]\n* {\n  box-sizing: border-box;\n}\n\nbody {\n  margin: 0;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n  background: #f5f5f5;\n  color: #333;\n}\n\nmain {\n  max-width: 800px;\n  margin: 0 auto;\n  padding: 2rem;\n}\n\nh1 {\n  font-size: 2.5rem;\n  margin-bottom: 0.5rem;\n}\n\n.card {\n  background: white;\n  border-radius: 8px;\n  padding: 2rem;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n  margin: 2rem 0;\n}\n\nbutton {\n  background: rgb(83, 91, 242);\n  color: white;\n  border: none;\n  padding: 0.5rem 1rem;\n  border-radius: 4px;\n  font-size: 1rem;\n  cursor: pointer;\n}\n\nbutton:hover {\n  background: #535bf2;\n}\n\n.subtitle {\n  color: #666;\n  font-size: 1.1rem;\n  margin-bottom: 2rem;\n}\n```\n\n```vue [app/pages/about.vue]\n<template>\n  <main>\n    <h1>About</h1>\n    <div class=\"card\">\n      <p>This is a simple Vue Router demo app built with Vite Plugin Fullstack.</p>\n      <p>It demonstrates basic routing and server-side rendering.</p>\n    </div>\n  </main>\n</template>\n```\n\n```vue [app/pages/index.vue]\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\n\nconst count = ref(0);\n\nfunction increment() {\n  count.value++;\n}\n</script>\n\n<template>\n  <main>\n    <div class=\"hero\">\n      <h1>Vue Router Custom Framework</h1>\n      <p class=\"subtitle\">A simple demo app with Vite</p>\n    </div>\n\n    <div class=\"card counter-card\">\n      <p>Count: {{ count }}</p>\n      <button @click=\"increment\">Increment</button>\n    </div>\n  </main>\n</template>\n\n<style scoped>\n.hero {\n  text-align: center;\n  margin-bottom: 2rem;\n}\n\n.hero h1 {\n  color: rgb(100, 108, 255);\n}\n\n.counter-card {\n  text-align: center;\n}\n\n.counter-card h2 {\n  color: #646cff;\n  margin-bottom: 1rem;\n}\n\n.counter-card p {\n  font-size: 1.5rem;\n  font-weight: bold;\n  margin: 1rem 0;\n}\n</style>\n```\n\n```vue [app/pages/not-found.vue]\n<template>\n  <main>\n    <h1>Not Found 404</h1>\n  </main>\n</template>\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-ssr-vue-router/README.md\" -->\n\nSet up server-side rendering (SSR) with Vue, Vue Router, Vite, and Nitro. This setup enables per-route code splitting, head management with unhead, and client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Define routes with lazy-loaded components\n3. Create a server entry that renders your app with router support\n4. Create a client entry that hydrates and takes over routing\n5. Create page components\n\n## 1. Configure Vite\n\nAdd the Nitro and Vue plugins to your Vite config. Define both `client` and `ssr` environments:\n\n```js [vite.config.mjs]\nimport vue from \"@vitejs/plugin-vue\";\nimport { defineConfig } from \"vite\";\nimport devtoolsJson from \"vite-plugin-devtools-json\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig((_env) => ({\n  plugins: [patchVueExclude(vue(), /\\?assets/), devtoolsJson(), nitro()],\n  environments: {\n    client: { build: { rollupOptions: { input: \"./app/entry-client.ts\" } } },\n    ssr: { build: { rollupOptions: { input: \"./app/entry-server.ts\" } } },\n  },\n}));\n\n// Workaround https://github.com/vitejs/vite-plugin-vue/issues/677\nfunction patchVueExclude(plugin, exclude) {\n  const original = plugin.transform.handler;\n  plugin.transform.handler = function (...args) {\n    if (exclude.test(args[1])) return;\n    return original.call(this, ...args);\n  };\n  return plugin;\n}\n```\n\nThe `patchVueExclude` helper prevents the Vue plugin from processing asset imports (files with `?assets` query parameter).\n\n## 2. Define Routes\n\nCreate route definitions with lazy-loaded components and asset metadata:\n\n```ts [app/routes.ts]\nimport type { RouteRecordRaw } from \"vue-router\";\n\nexport const routes: RouteRecordRaw[] = [\n  {\n    path: \"/\",\n    name: \"app\",\n    component: () => import(\"./app.vue\"),\n    meta: {\n      assets: () => import(\"./app.vue?assets\"),\n    },\n    children: [\n      {\n        path: \"/\",\n        name: \"home\",\n        component: () => import(\"./pages/index.vue\"),\n        meta: {\n          assets: () => import(\"./pages/index.vue?assets\"),\n        },\n      },\n      {\n        path: \"/about\",\n        name: \"about\",\n        component: () => import(\"./pages/about.vue\"),\n        meta: {\n          assets: () => import(\"./pages/about.vue?assets\"),\n        },\n      },\n      {\n        path: \"/:catchAll(.*)\",\n        name: \"not-found\",\n        component: () => import(\"./pages/not-found.vue\"),\n        meta: {\n          assets: () => import(\"./pages/not-found.vue?assets\"),\n        },\n      },\n    ],\n  },\n];\n```\n\nUse dynamic imports for lazy-loaded components to enable code splitting. The `meta.assets` function loads route-specific CSS and JS chunks. Define child routes under a root layout component for nested routing.\n\n## 3. Create the Server Entry\n\nThe server entry renders your Vue app with router support and head management:\n\n```ts [app/entry-server.ts]\nimport { createSSRApp } from \"vue\";\nimport { renderToString } from \"vue/server-renderer\";\nimport { RouterView, createMemoryHistory, createRouter } from \"vue-router\";\nimport { createHead, transformHtmlTemplate } from \"unhead/server\";\n\nimport { routes } from \"./routes.ts\";\n\nimport clientAssets from \"./entry-client.ts?assets=client\";\n\nasync function handler(request: Request): Promise<Response> {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createMemoryHistory(), routes });\n  app.use(router);\n\n  const url = new URL(request.url);\n  const href = url.href.slice(url.origin.length);\n\n  await router.push(href);\n  await router.isReady();\n\n  const assets = clientAssets.merge(\n    ...(await Promise.all(\n      router.currentRoute.value.matched\n        .map((to) => to.meta.assets)\n        .filter(Boolean)\n        .map((fn) => (fn as any)().then((m: any) => m.default))\n    ))\n  );\n\n  const head = createHead();\n\n  head.push({\n    link: [\n      ...assets.css.map((attrs: any) => ({ rel: \"stylesheet\", ...attrs })),\n      ...assets.js.map((attrs: any) => ({ rel: \"modulepreload\", ...attrs })),\n    ],\n    script: [{ type: \"module\", src: clientAssets.entry }],\n  });\n\n  const renderedApp = await renderToString(app);\n\n  const html = await transformHtmlTemplate(head, htmlTemplate(renderedApp));\n\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n  });\n}\n\nfunction htmlTemplate(body: string): string {\n  return /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>Vue Router Custom Framework</title>\n</head>\n<body>\n  <div id=\"root\">${body}</div>\n</body>\n</html>`;\n}\n\nexport default {\n  fetch: handler,\n};\n```\n\nThe server uses `createMemoryHistory()` since there's no browser URL bar—the router navigates to the requested URL before rendering. Assets are loaded dynamically based on matched routes, ensuring only the CSS and JS needed for the current page are included. The `unhead` library manages `<head>` elements, injecting stylesheets and scripts via `transformHtmlTemplate`.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML and takes over routing:\n\n```ts [app/entry-client.ts]\nimport { createSSRApp } from \"vue\";\nimport { RouterView, createRouter, createWebHistory } from \"vue-router\";\nimport { routes } from \"./routes.ts\";\n\nasync function main() {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createWebHistory(), routes });\n  app.use(router);\n\n  await router.isReady();\n  app.mount(\"#root\");\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain();\n```\n\nThe client entry creates a Vue app with `createWebHistory()` for browser-based routing. After the router is ready, it mounts to the `#root` element and hydrates the server-rendered HTML.\n\n## 5. Create the Root Component\n\nThe root component provides navigation and renders child routes:\n\n```vue [app/app.vue]\n<script setup lang=\"ts\">\nimport { RouterLink, RouterView } from \"vue-router\";\nimport \"./styles.css\";\n</script>\n\n<template>\n  <nav>\n    <ul>\n      <li>\n        <RouterLink to=\"/\" exact-active-class=\"active\">Home</RouterLink>\n      </li>\n      <li>\n        <RouterLink to=\"/about\" active-class=\"active\">About</RouterLink>\n      </li>\n    </ul>\n  </nav>\n  <RouterView />\n</template>\n\n<style scoped>\nnav {\n  background: white;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  padding: 1rem;\n}\n\nnav ul {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  display: flex;\n  gap: 2rem;\n  max-width: 800px;\n  margin: 0 auto;\n}\n\nnav a {\n  color: #666;\n  text-decoration: none;\n}\n\nnav a:hover {\n  color: #333;\n}\n\nnav a.active {\n  color: #646cff;\n}\n</style>\n```\n\n<!-- /automd -->\n\n## Learn More\n\n- [Vue Router Documentation](https://router.vuejs.org/)\n- [Unhead Documentation](https://unhead.unjs.io/)\n- [Renderer](/docs/renderer)\n- [Server Entry](/docs/server-entry)\n"
  },
  {
    "path": "docs/4.examples/vite-trpc.md",
    "content": "---\ncategory: vite\nicon: i-simple-icons-trpc\n---\n\n# Vite + tRPC\n\n> End-to-end typesafe APIs with tRPC in Nitro using Vite.\n\n<!-- automd:ui-code-tree src=\"../../examples/vite-trpc\" default=\"server/trpc.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"server/trpc.ts\" expandAll}\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>tRPC Counter</title>\n    <style>\n      body {\n        font-family: system-ui, sans-serif;\n        background: #0f1115;\n        color: #e5e7eb;\n        display: grid;\n        place-items: center;\n        height: 100vh;\n        margin: 0;\n      }\n\n      .box {\n        background: #181b22;\n        padding: 24px 32px;\n        border-radius: 10px;\n        text-align: center;\n        min-width: 200px;\n      }\n\n      button {\n        background: #2563eb;\n        border: none;\n        color: white;\n        padding: 8px 14px;\n        border-radius: 6px;\n        cursor: pointer;\n        margin-top: 12px;\n        font-size: 14px;\n      }\n\n      button:hover {\n        background: #1d4ed8;\n      }\n\n      .value {\n        font-size: 36px;\n        margin: 12px 0;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"box\">\n      <div>Counter</div>\n      <div class=\"value\" id=\"value\">\n        <script server>\n          // Server-side Rendering\n          const { result } = await serverFetch(\"/trpc/get\").then(r => r.json())\n          echo(result?.data?.value)\n        </script>\n      </div>\n      <button id=\"inc\">Increment</button>\n    </div>\n\n    <script setup>\n      const valueEl = document.getElementById(\"value\");\n      const incBtn = document.getElementById(\"inc\");\n\n      async function call(path, body) {\n        const res = await fetch(`/trpc/${path}`, {\n          method: body ? \"POST\" : \"GET\",\n          headers: { \"content-type\": \"application/json\" },\n          body: body ? JSON.stringify(body) : undefined,\n        });\n\n        const json = await res.json();\n        return json.result.data;\n      }\n\n      async function refresh() {\n        const data = await call(\"get\");\n        valueEl.textContent = data.value;\n      }\n\n      incBtn.onclick = async () => {\n        const data = await call(\"inc\", {});\n        valueEl.textContent = data.value;\n      };\n\n      refresh();\n    </script>\n  </body>\n</html>\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@trpc/client\": \"^11.13.4\",\n    \"@trpc/server\": \"^11.13.4\",\n    \"nitro\": \"latest\",\n    \"vite\": \"latest\",\n    \"zod\": \"^4.3.6\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {}\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro({\n      routes: {\n        \"/trpc/**\": \"./server/trpc.ts\",\n      },\n    }),\n  ],\n});\n```\n\n```ts [server/trpc.ts]\nimport { initTRPC } from \"@trpc/server\";\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\n\nlet counter = 0;\n\nconst t = initTRPC.create();\n\nexport const appRouter = t.router({\n  get: t.procedure.query(() => {\n    return { value: counter };\n  }),\n\n  inc: t.procedure.mutation(() => {\n    counter++;\n    return { value: counter };\n  }),\n});\n\nexport type AppRouter = typeof appRouter;\n\nexport default {\n  async fetch(request: Request): Promise<Response> {\n    return fetchRequestHandler({\n      endpoint: \"/trpc\",\n      req: request,\n      router: appRouter,\n    });\n  },\n};\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/vite-trpc/README.md\" -->\n\nSet up tRPC with Vite and Nitro for end-to-end typesafe APIs without code generation. This example builds a counter with server-side rendering for the initial value and client-side updates.\n\n## Overview\n\n1. Configure Vite with the Nitro plugin and route tRPC requests\n2. Create a tRPC router with procedures\n3. Create an HTML page with server-side rendering and client interactivity\n\n## 1. Configure Vite\n\nAdd the Nitro plugin and configure the `/trpc/**` route to point to your tRPC handler:\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro({\n      routes: {\n        \"/trpc/**\": \"./server/trpc.ts\",\n      },\n    }),\n  ],\n});\n```\n\nThe `routes` option maps URL patterns to handler files. All requests to `/trpc/*` are handled by the tRPC router.\n\n## 2. Create the tRPC Router\n\nDefine your tRPC router with procedures and export it as a fetch handler:\n\n```ts [server/trpc.ts]\nimport { initTRPC } from \"@trpc/server\";\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\n\nlet counter = 0;\n\nconst t = initTRPC.create();\n\nexport const appRouter = t.router({\n  get: t.procedure.query(() => {\n    return { value: counter };\n  }),\n\n  inc: t.procedure.mutation(() => {\n    counter++;\n    return { value: counter };\n  }),\n});\n\nexport type AppRouter = typeof appRouter;\n\nexport default {\n  async fetch(request: Request): Promise<Response> {\n    return fetchRequestHandler({\n      endpoint: \"/trpc\",\n      req: request,\n      router: appRouter,\n    });\n  },\n};\n```\n\nDefine procedures using `t.procedure.query()` for read operations and `t.procedure.mutation()` for write operations. Export the `AppRouter` type so clients get full type inference. The default export uses tRPC's fetch adapter to handle incoming requests.\n\n## 3. Create the HTML Page\n\nCreate an HTML page with server-side rendering and client-side interactivity:\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>tRPC Counter</title>\n    <style>\n      body {\n        font-family: system-ui, sans-serif;\n        background: #0f1115;\n        color: #e5e7eb;\n        display: grid;\n        place-items: center;\n        height: 100vh;\n        margin: 0;\n      }\n\n      .box {\n        background: #181b22;\n        padding: 24px 32px;\n        border-radius: 10px;\n        text-align: center;\n        min-width: 200px;\n      }\n\n      button {\n        background: #2563eb;\n        border: none;\n        color: white;\n        padding: 8px 14px;\n        border-radius: 6px;\n        cursor: pointer;\n        margin-top: 12px;\n        font-size: 14px;\n      }\n\n      button:hover {\n        background: #1d4ed8;\n      }\n\n      .value {\n        font-size: 36px;\n        margin: 12px 0;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"box\">\n      <div>Counter</div>\n      <div class=\"value\" id=\"value\">\n        <script server>\n          // Server-side Rendering\n          const { result } = await serverFetch(\"/trpc/get\").then(r => r.json())\n          echo(result?.data?.value)\n        </script>\n      </div>\n      <button id=\"inc\">Increment</button>\n    </div>\n\n    <script setup>\n      const valueEl = document.getElementById(\"value\");\n      const incBtn = document.getElementById(\"inc\");\n\n      async function call(path, body) {\n        const res = await fetch(`/trpc/${path}`, {\n          method: body ? \"POST\" : \"GET\",\n          headers: { \"content-type\": \"application/json\" },\n          body: body ? JSON.stringify(body) : undefined,\n        });\n\n        const json = await res.json();\n        return json.result.data;\n      }\n\n      async function refresh() {\n        const data = await call(\"get\");\n        valueEl.textContent = data.value;\n      }\n\n      incBtn.onclick = async () => {\n        const data = await call(\"inc\", {});\n        valueEl.textContent = data.value;\n      };\n\n      refresh();\n    </script>\n  </body>\n</html>\n```\n\nThe `<script server>` block runs on the server before sending the response, fetching the initial counter value via `serverFetch`. The `<script setup>` block runs in the browser and handles the increment button click.\n\n<!-- /automd -->\n\n## Learn More\n\n- [tRPC](https://trpc.io/)\n- [Routing](/docs/routing)\n"
  },
  {
    "path": "docs/4.examples/websocket.md",
    "content": "---\ncategory: features\nicon: i-lucide-radio\n---\n\n# WebSocket\n\n> Real-time bidirectional communication with WebSocket support.\n\n<!-- automd:ui-code-tree src=\"../../examples/websocket\" default=\"routes/_ws.ts\" ignore=\"README.md,GUIDE.md\" expandAll -->\n\n::code-tree{defaultValue=\"routes/_ws.ts\" expandAll}\n\n```html [index.html]\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <title>CrossWS Test Page</title>\n    <script src=\"https://cdn.tailwindcss.com\"></script>\n    <style>\n      body {\n        background-color: #1a1a1a;\n      }\n    </style>\n    <script type=\"module\">\n      import { createApp, reactive, nextTick } from \"https://esm.sh/petite-vue@0.4.1\";\n\n      let ws;\n\n      const store = reactive({\n        message: \"\",\n        messages: [],\n      });\n\n      const scroll = () => {\n        nextTick(() => {\n          const el = document.querySelector(\"#messages\");\n          el.scrollTop = el.scrollHeight;\n          el.scrollTo({\n            top: el.scrollHeight,\n            behavior: \"smooth\",\n          });\n        });\n      };\n\n      const format = async () => {\n        for (const message of store.messages) {\n          if (!message._fmt && message.text.startsWith(\"{\")) {\n            message._fmt = true;\n            const { codeToHtml } = await import(\"https://esm.sh/shiki@1.0.0\");\n            const str = JSON.stringify(JSON.parse(message.text), null, 2);\n            message.formattedText = await codeToHtml(str, {\n              lang: \"json\",\n              theme: \"dark-plus\",\n            });\n          }\n        }\n      };\n\n      const log = (user, ...args) => {\n        console.log(\"[ws]\", user, ...args);\n        store.messages.push({\n          text: args.join(\" \"),\n          formattedText: \"\",\n          user: user,\n          date: new Date().toLocaleString(),\n        });\n        scroll();\n        format();\n      };\n\n      const connect = async () => {\n        const isSecure = location.protocol === \"https:\";\n        const url = (isSecure ? \"wss://\" : \"ws://\") + location.host + \"/_ws\";\n        if (ws) {\n          log(\"ws\", \"Closing previous connection before reconnecting...\");\n          ws.close();\n          clear();\n        }\n\n        log(\"ws\", \"Connecting to\", url, \"...\");\n        ws = new WebSocket(url);\n\n        ws.addEventListener(\"message\", async (event) => {\n          let data = typeof event.data === \"string\" ? event.data : await event.data.text();\n          const { user = \"system\", message = \"\" } = data.startsWith(\"{\")\n            ? JSON.parse(data)\n            : { message: data };\n          log(user, typeof message === \"string\" ? message : JSON.stringify(message));\n        });\n\n        await new Promise((resolve) => ws.addEventListener(\"open\", resolve));\n        log(\"ws\", \"Connected!\");\n      };\n\n      const clear = () => {\n        store.messages.splice(0, store.messages.length);\n        log(\"system\", \"previous messages cleared\");\n      };\n\n      const send = () => {\n        console.log(\"sending message...\");\n        if (store.message) {\n          ws.send(store.message);\n        }\n        store.message = \"\";\n      };\n\n      const ping = () => {\n        log(\"ws\", \"Sending ping\");\n        ws.send(\"ping\");\n      };\n\n      createApp({\n        store,\n        send,\n        ping,\n        clear,\n        connect,\n        rand: Math.random(),\n      }).mount();\n\n      await connect();\n    </script>\n  </head>\n  <body class=\"h-screen flex flex-col justify-between\">\n    <main v-scope=\"{}\">\n      <!-- Messages -->\n      <div id=\"messages\" class=\"flex-grow flex flex-col justify-end px-4 py-8\">\n        <div class=\"flex items-center mb-4\" v-for=\"message in store.messages\">\n          <div class=\"flex flex-col\">\n            <p class=\"text-gray-500 mb-1 text-xs ml-10\">{{ message.user }}</p>\n            <div class=\"flex items-center\">\n              <img\n                :src=\"'https://www.gravatar.com/avatar/' + encodeURIComponent(message.user + rand) + '?s=512&d=monsterid'\"\n                alt=\"Avatar\"\n                class=\"w-8 h-8 rounded-full\"\n              />\n              <div class=\"ml-2 bg-gray-800 rounded-lg p-2\">\n                <p\n                  v-if=\"message.formattedText\"\n                  class=\"overflow-x-scroll\"\n                  v-html=\"message.formattedText\"\n                ></p>\n                <p v-else class=\"text-white\">{{ message.text }}</p>\n              </div>\n            </div>\n            <p class=\"text-gray-500 mt-1 text-xs ml-10\">{{ message.date }}</p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Chatbox -->\n      <div class=\"bg-gray-800 px-4 py-2 flex items-center justify-between fixed bottom-0 w-full\">\n        <div class=\"w-full min-w-6\">\n          <input\n            type=\"text\"\n            placeholder=\"Type your message...\"\n            class=\"w-full rounded-l-lg px-4 py-2 bg-gray-700 text-white focus:outline-none focus:ring focus:border-blue-300\"\n            @keydown.enter=\"send\"\n            v-model=\"store.message\"\n          />\n        </div>\n        <div class=\"flex\">\n          <button class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4\" @click=\"send\">\n            Send\n          </button>\n          <button class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4\" @click=\"ping\">\n            Ping\n          </button>\n          <button class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4\" @click=\"connect\">\n            Reconnect\n          </button>\n          <button\n            class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-r-lg\"\n            @click=\"clear\"\n          >\n            Clear\n          </button>\n        </div>\n      </div>\n    </main>\n  </body>\n</html>\n`\n```\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  renderer: { static: true },\n  features: { websocket: true },\n});\n```\n\n```json [package.json]\n{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \"nitro/tsconfig\"\n}\n```\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n```\n\n```ts [routes/_ws.ts]\nimport { defineWebSocketHandler } from \"nitro\";\n\nexport default defineWebSocketHandler({\n  open(peer) {\n    peer.send({ user: \"server\", message: `Welcome ${peer}!` });\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} joined!` });\n    peer.subscribe(\"chat\");\n  },\n  message(peer, message) {\n    if (message.text().includes(\"ping\")) {\n      peer.send({ user: \"server\", message: \"pong\" });\n    } else {\n      const msg = {\n        user: peer.toString(),\n        message: message.toString(),\n      };\n      peer.send(msg); // echo\n      peer.publish(\"chat\", msg);\n    }\n  },\n  close(peer) {\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} left!` });\n  },\n});\n```\n\n::\n\n<!-- /automd -->\n\n<!-- automd:file src=\"../../examples/websocket/README.md\" -->\n\nThis example implements a simple chat room using WebSockets. Clients connect, send messages, and receive messages from other users in real-time. The server broadcasts messages to all connected clients using pub/sub channels.\n\n## WebSocket Handler\n\nCreate a WebSocket route using `defineWebSocketHandler`.\n\n```ts [routes/_ws.ts]\nimport { defineWebSocketHandler } from \"nitro\";\n\nexport default defineWebSocketHandler({\n  open(peer) {\n    peer.send({ user: \"server\", message: `Welcome ${peer}!` });\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} joined!` });\n    peer.subscribe(\"chat\");\n  },\n  message(peer, message) {\n    if (message.text().includes(\"ping\")) {\n      peer.send({ user: \"server\", message: \"pong\" });\n    } else {\n      const msg = {\n        user: peer.toString(),\n        message: message.toString(),\n      };\n      peer.send(msg); // echo\n      peer.publish(\"chat\", msg);\n    }\n  },\n  close(peer) {\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} left!` });\n  },\n});\n```\n\nDifferent hooks are exposed by `defineWebSocketHandler()` to integrate with different parts of the websocket lifecycle.\n\n<!-- /automd -->\n\n## Learn More\n\n- [Routing](/docs/routing)\n- [crossws Documentation](https://crossws.h3.dev/guide/hooks)\n"
  },
  {
    "path": "docs/9.blog/1.v3-beta.md",
    "content": "---\ndate: 2026-03-11\ncategory: release\nauthors:\n  - name: Pooya Parsa\n    github: pi0\n---\n\n# Nitro v3 Beta is here!\n\n> Nitro v3 is now available as a public beta — a ground-up evolution of the server framework, built around web standards, Rolldown, Vite v8, and the same deploy-anywhere promise.\n\n<!-- 👉 Already on Nitro v2? Check out the [migration guide](/docs/migration). -->\n\n## A Brief History\n\nNitro started as the server engine for [Nuxt 3](https://nuxt.com), designed to solve a specific problem: deployment-agnostic servers.\nOver time, Nitro grew beyond Nuxt. It became the foundation for many meta-frameworks and a toolkit for building standalone servers.\n\nWith Nitro v3, we took the opportunity to rethink the fundamentals. leaner APIs, Web standards, first-class [Rolldown](https://rolldown.rs/) and [Vite v8](https://vite.dev/) integration, and a better experience for both humans and agents (more on that later!)\n\nSince we quietly announced v3 [alpha.0](https://github.com/nitrojs/nitro/releases/tag/v3.0.1-alpha.0) (11 Oct 2025) at the first [Vite Conf](https://viteconf.amsterdam/), Nitro v3 has been adopted by many users ([~280k](https://npmtrends.com/nitro-vs-nitro-nightly) weekly downloads!) and refined through amazing contributions and feedback. including [Tanstack Start](https://tanstack.com/start/latest/docs/framework/react/guide/hosting#nitro), [Vercel Workflows](https://useworkflow.dev/docs/getting-started), and production apps like [T3Chat](https://t3.chat/).\n\nA huge thanks to the VoidZero (Vite and Rolldown), Nuxt ([v5 is coming!](#nuxt-v5)) and TanStack Start teams and every contributor who helped bring Nitro v3 to this milestone. ❤️\n\n## Why Build Servers?\n\nWe don't ship raw source files to the browser. We use build tools because they solve real problems: **HMR** for instant feedback, **code splitting** to load only what a route needs, **tree shaking** to eliminate dead code, and **minification** for smaller payloads. Tools like Webpack and then [Vite](https://vite.dev/) transformed frontend development from painful to productive.\n\nBut frontend apps don't exist in isolation, they need APIs, databases, authentication, real-time data. They need a server.\n\nWith the rise of serverless and edge computing, the server side now faces the same constraints the frontend solved years ago. **Cold starts** mean every millisecond of startup matters. **Memory limits** are strict — bloated dependencies can push you over. **Bundle size** directly impacts deploy speed and boot time. And your code needs to run everywhere: Node.js, Deno, Bun, Cloudflare Workers, Vercel, etc. Yet most server frameworks still ship unoptimized, unbundled code, assuming a long-running process where none of this matters.\n\nNitro brings the build-tool philosophy to the backend. The same great DX you expect from frontend tooling: HMR for fast iteration and optimized builds powered by Rolldown with tree-shaken production output that performs as close to bare-metal as possible. **One codebase, any runtime, any platform.**\n\n## ⚡ First-Class Vite Integration\n\nNitro now has a native [Vite](https://vite.dev) plugin to build full stack apps.\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n```\n\nAdding `nitro()` to your Vite apps gives you:\n\n- **API routes** via filesystem routing\n- **Server-side rendering** integrated with your frontend build\n- **A production server** — a single `vite build` produces an optimized `.output/` folder with both frontend and backend, ready to deploy\n\nThis means you can add a full backend to any Vite project — See [examples](/examples) with [React](/examples/vite-ssr-react), [Vue](/examples/vite-ssr-vue-router) and [Solid.js](/examples/vite-ssr-solid).\n\n## 🚀 Performance by Default, Zero Bloat\n\nNitro compiles your routes at build time. There is no runtime router — each route loads on demand. Only the code needed to handle a specific request is loaded and executed.\n\nMinimal server bundle built with the `standard` preset is less than `10kB`, can be served with [srvx](https://srvx.h3.dev/) at close to native speeds, and includes all the good features from [H3](https://h3.dev/).\n\nWe have also significantly reduced the number of dependencies, down to [less than 20](https://npmgraph.js.org/?q=nitro-nightly) from [321 dependencies](https://npmgraph.js.org/?q=nitropack).\n\n## 🖌️ New Identity: `nitro`\n\nNitro v3 ships under a new NPM package: [`nitro`](https://npmx.dev/package/nitro), replacing the legacy `nitropack`.\n\nAll imports now use clean `nitro/*` subpaths:\n\n```ts\nimport { defineNitroConfig } from \"nitro/config\";\nimport { defineHandler } from \"nitro\";\nimport { useStorage } from \"nitro/storage\";\nimport { useDatabase } from \"nitro/database\";\n```\n\nNo more deep `nitropack/runtime/*` paths, plus, you can import nitro subpaths outside of builder useful for unit testing.\n\n## 🔧 Bring Your Own Framework\n\nNitro v3 is not opinionated about your HTTP layer. You can use the built-in filesystem routing, or take full control with a `server.ts` entry file and bring any framework you prefer:\n\n```ts [server.ts]\nimport { Hono } from \"hono\";\n\nconst app = new Hono();\napp.get(\"/\", (c) => c.text(\"Hello from Hono!\"));\n\nexport default app;\n```\n\n## 🌐 H3 (v2) with Web Standards\n\nNitro v3 upgrades to [H3 v2](https://h3.dev), which has been fully rewritten around web standard primitives — [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request), [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response), [`Headers`](https://developer.mozilla.org/en-US/docs/Web/API/Headers), and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL).\n\nThe result is cleaner, more portable server code:\n\n```ts [routes/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => {\n  const ua = event.req.headers.get(\"user-agent\");\n  return { message: \"Hello Nitro v3!\", ua };\n});\n```\n\nReading request bodies uses native APIs:\n\n```ts [routes/submit.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const body = await event.req.json();\n  return { received: body };\n});\n```\n\nNo wrappers, no abstractions for things the platform already provides. If you know the Web API, you know H3 v2.\n\n[Elysia](https://elysiajs.com/), [h3](https://h3.dev), [Hono](https://hono.dev) — anything that speaks web standards works with Nitro.\n\n## 🗄️ Built-in Primitives\n\nNitro ships with powerful but small and **fully opt-in** agnostic server primitives that work across every runtime.\n\n::note\nWhen not used, nothing extra will be added to the server bundle. You can still use native platform primitives alongside Nitro's built-in ones.\nWe are also bringing first class emulation for platform-specific primitives for dev See [env-runner](https://github.com/unjs/env-runner) and [nitrojs/nitro#4088](https://github.com/nitrojs/nitro/pull/4088) for more details.\n::\n\n### Storage\n\nA runtime-agnostic key-value layer with 20+ drivers — FS, Redis, S3, Cloudflare KV, Vercel Blob and [more](https://unstorage.unjs.io/drivers). Attach drivers to namespaces and swap them without changing your application code.\n\n```ts\nimport { useStorage } from \"nitro/storage\";\n\nconst storage = useStorage();\nawait storage.setItem(\"user:1\", { name: \"Nitro\" });\n```\n\n:read-more{to=\"/docs/storage\"}\n\n### Caching\n\nCache server routes and functions, backed by the storage layer. Supports stale-while-revalidate, TTL, and custom cache keys out of the box.\n\n```ts\nimport { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler((event) => {\n  return \"I am cached for an hour\";\n}, { maxAge: 60 * 60 });\n```\n\n:read-more{to=\"/docs/cache\"}\n\n### Database\n\nA built-in SQL database that defaults to SQLite for development and can connect to Postgres, MySQL, and [more](https://db0.unjs.io/connectors) using the same API.\n\n```ts\nimport { useDatabase } from \"nitro/database\";\n\nconst db = useDatabase();\nconst users = await db.sql`SELECT * FROM users`;\n```\n\n:read-more{to=\"/docs/database\"}\n\n## 🌍 Deploy Anywhere\n\nBuild your server into an optimized `.output/` folder compatible with:\n\n- **Runtimes**: Node.js, Bun, Deno\n- **Platforms**: Cloudflare Workers, Netlify, Vercel, AWS Lambda, Azure, Firebase, Deno Deploy, and more\n\nNo configuration needed — Nitro auto-detects your deployment target. Take advantage of platform features like ISR, SWR, and edge rendering without changing a single line of code.\n\n## 🎨 Server-Side Rendering\n\nRender HTML with your favorite templating engine, or use component libraries like React, Vue, or Svelte directly on the server. Go full universal rendering with client-side hydration.\n\nNitro provides the foundation and a progressive approach — start with API routes, add rendering when you need it, and scale to full SSR at your own pace.\n\n:read-more{to=\"/docs/renderer\"}\n\n## 🟢 Nuxt v5\n\nNitro v3 will power the next major version of [Nuxt](https://nuxt.com).\n\n[Nuxt v5](https://nuxt.com/blog/roadmap-v4) will ship with Nitro v3 and H3 v2 at its core, bringing web-standard request handling, Rolldown-powered builds, and the Vite Environment API to the Nuxt ecosystem.\n\nIf you're a Nuxt user, you can already start preparing by familiarizing yourself with  Nitro v3's new APIs, which will carry directly into Nuxt 5, and you can [follow progress](https://github.com/nuxt/nuxt/discussions/34504) on adopting Nitro v3 in Nuxt\n\n## 🏁 Getting Started\n\n### Create a New Project\n\n:pm-x{command=\"create-nitro-app\"}\n\nSee the [quick start guide](/docs/quick-start) for a full step-by-step walkthrough.\n\n## 🔄 Migrating from v2\n\nNitro v3 introduces intentional breaking changes to set a cleaner foundation. Here are the key ones:\n\n- `nitropack` → `nitro` (package rename)\n- `nitropack/runtime/*` → `nitro/*` (clean subpath imports)\n- `eventHandler` → `defineHandler` (H3 v2)\n- `createError` → `HTTPError` (H3 v2)\n- Web standard `event.req` headers and body APIs\n- Node.js minimum version: **20**\n- Preset renames and consolidation (e.g., `cloudflare` → `cloudflare_module`)\n\nFor a complete list, see the [migration guide](/docs/migration).\n\n---\n\nThank you to everyone who has contributed to Nitro over the years. We can't wait to see what you build with the new Nitro! ❤️\n\n- [GitHub](https://github.com/nitrojs/nitro) — Issues and discussions\n- [Discord](https://discord.nitro.build) — Chat with the community\n"
  },
  {
    "path": "docs/9.blog/index.md",
    "content": "# Blog\n\nNitro blog posts.\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\nseo:\n  title: Build Full-Stack Servers\n  description: Nitro extends your Vite application with a production-ready server, compatible with any runtime. Add server routes to your application and deploy many hosting platform with a zero-config experience.\n---\n\n::u-page-hero\n---\norientation: horizontal\n---\n::code-group\n  :::prose-pre\n  ---\n  filename: vite.config.ts\n  ---\n  ```ts\n  import { defineConfig } from 'vite'\n  import { nitro } from 'nitro/vite'\n\n  export default defineConfig({\n    plugins: [nitro()],\n    nitro: {\n      serverDir: \"./server\"\n    }\n  })\n  ```\n  :::\n  :::prose-pre\n  ---\n  filename: nitro.config.ts\n  ---\n  ```ts\n  import { defineConfig } from 'nitro'\n\n  export default defineConfig({\n    preset: \"node\",\n    serverDir: \"./server\",\n    routeRules: {\n      \"/api/**\": { cache: true }\n    }\n  })\n  ```\n  :::\n::\n\n:hero-background\n\n#title\nBuild [/Servers]{.text-primary}\n\n#description\nNitro extends your Vite application with a production-ready server, compatible with any runtime. Add server routes to your application and deploy many hosting platform with a zero-config experience.\n\n#links\n:app-hero-links\n::\n\n::hero-features\n---\nfeatures:\n  - title: Fast\n    description: Enjoy the fast Vite 8 (rolldown powered) development experience with HMR on the server and optimized for production.\n    icon: i-lucide-zap\n    color: text-amber-500\n    bgColor: bg-amber-500/10\n    borderColor: \"group-hover:border-amber-500/30\"\n  - title: Agnostic\n    description: Deploy the same codebase to any deployment provider with zero config and locked-in.\n    icon: i-lucide-globe\n    color: text-sky-500\n    bgColor: bg-sky-500/10\n    borderColor: \"group-hover:border-sky-500/30\"\n  - title: Minimal\n    description: Nitro adds no overhead to runtime. Build your servers with any modern tool you like.\n    icon: i-lucide-feather\n    color: text-emerald-500\n    bgColor: bg-emerald-500/10\n    borderColor: \"group-hover:border-emerald-500/30\"\n---\n::\n\n::performance-showcase\n---\nmetrics:\n  - label: Bare metal perf\n    value: \"~Native\"\n    unit: RPS\n    description: Using compile router, and fast paths for request handling.\n    icon: i-lucide-gauge\n    color: text-emerald-500\n    bgColor: bg-emerald-500/10\n    barWidth: \"95%\"\n    barColor: bg-emerald-500\n  - label: Minimum install Size\n    value: Tiny\n    unit: deps\n    description: Minimal dependencies. No bloated node_modules.\n    icon: i-lucide-package\n    color: text-sky-500\n    bgColor: bg-sky-500/10\n    barWidth: \"15%\"\n    barColor: bg-sky-500\n  - label: Small and portable output\n    value: \"‹ 10\"\n    unit: kB\n    description: Standard server builds produce ultra-small output bundles.\n    icon: i-lucide-file-output\n    color: text-violet-500\n    bgColor: bg-violet-500/10\n    barWidth: \"10%\"\n    barColor: bg-violet-500\n  - label: FAST builds\n    value: \"‹ 1\"\n    unit: sec\n    description: Cold production builds complete in seconds, not minutes.\n    icon: i-lucide-timer\n    color: text-amber-500\n    bgColor: bg-amber-500/10\n    barWidth: \"12%\"\n    barColor: bg-amber-500\n---\n::\n\n::landing-features\n#body\n  :::feature-card\n  ---\n  headline: Routing\n  link: /docs/routing\n  link-label: Routing docs\n  ---\n  #title\n  File-system routing\n\n  #description\n  Create server routes in the routes/ folder and they are automatically registered. Or bring your own framework — H3, Hono, Elysia, Express — via a server.ts entry.\n  :::\n\n  :::feature-card\n  ---\n  headline: Versatile\n  link: /deploy\n  link-label: Explore deploy targets\n  ---\n  #title\n  Deploy everywhere\n\n  #description\n  The same codebase deploys to Node.js, Cloudflare Workers, Deno, Bun, AWS Lambda, Vercel, Netlify, and more — zero config, no vendor lock-in.\n  :::\n\n  :::feature-card\n  ---\n  headline: Storage\n  link: /docs/storage\n  link-label: Storage docs\n  ---\n  #title\n  Universal storage\n\n  #description\n  Built-in key-value storage abstraction powered by unstorage. Works with filesystem, Redis, Cloudflare KV, and more — same API everywhere.\n  :::\n\n  :::feature-card\n  ---\n  headline: Caching\n  link: /docs/cache\n  link-label: Caching docs\n  ---\n  #title\n  Built-in caching\n\n  #description\n  Cache route handlers and arbitrary functions with a simple API. Supports multiple storage backends and stale-while-revalidate patterns.\n  :::\n\n  :::feature-card\n  ---\n  headline: Server Entry\n  link: /docs/server-entry\n  link-label: Server entry docs\n  ---\n  #title\n  Web standard server\n\n  #description\n  Go full Web standard and pick the library of your choice. Use H3, Hono, Elysia, Express, or the raw fetch API — Nitro handles the rest.\n  :::\n\n  :::feature-card\n  ---\n  headline: Renderer\n  link: /docs/renderer\n  link-label: Renderer docs\n  ---\n  #title\n  Universal renderer\n\n  #description\n  Use any frontend framework as your renderer. Nitro provides the server layer while your framework handles the UI.\n  :::\n\n  :::feature-card\n  ---\n  headline: Plugins\n  link: /docs/plugins\n  link-label: Plugins docs\n  ---\n  #title\n  Server plugins\n\n  #description\n  Extend Nitro's runtime behavior with plugins. Hook into lifecycle events, register custom logic, and auto-load from the plugins/ directory.\n  :::\n\n  :::feature-card\n  ---\n  headline: Database\n  link: /docs/database\n  link-label: Database docs\n  ---\n  #title\n  Built-in database\n\n  #description\n  Lightweight SQL database layer powered by db0. Pre-configured with SQLite out of the box, with support for PostgreSQL, MySQL, and Cloudflare D1.\n  :::\n\n  :::feature-card\n  ---\n  headline: Assets\n  link: /docs/assets\n  link-label: Assets docs\n  ---\n  #title\n  Static & server assets\n\n  #description\n  Serve public assets directly to clients or bundle server assets for programmatic access. Works seamlessly across all deployment targets.\n  :::\n::\n\n\n::page-sponsors\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"undocs dev\",\n    \"build\": \"undocs build\"\n  },\n  \"devDependencies\": {\n    \"automd\": \"^0.4.3\",\n    \"geist\": \"^1.7.0\",\n    \"motion-v\": \"^2.0.0\",\n    \"shaders\": \"^2.3.75\",\n    \"undocs\": \"npm:undocs-nightly@0.4.17-20260310-213525-c3c295a\",\n    \"zod\": \"^4.3.6\"\n  }\n}\n"
  },
  {
    "path": "docs/pnpm-workspace.yaml",
    "content": "packages: []\n\nignoredBuiltDependencies:\n  - '@parcel/watcher'\n  - '@tailwindcss/oxide'\n  - esbuild\n  - vue-demi\n\nonlyBuiltDependencies:\n  - better-sqlite3\n"
  },
  {
    "path": "examples/api-routes/README.md",
    "content": "Nitro supports file-based routing in the `api/` or `routes/` directory. Each file becomes an API endpoint based on its path.\n\n## Basic Route\n\nCreate a file in the `api/` directory to define a route. The file path becomes the URL path:\n\n```ts [api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n```\n\nThis creates a `GET /api/hello` endpoint.\n\n## Dynamic Routes\n\nUse square brackets `[param]` for dynamic URL segments. Access params via `event.context.params`:\n\n```ts [api/hello/[name].ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => `Hello (param: ${event.context.params!.name})!`);\n```\n\nThis creates a `GET /api/hello/:name` endpoint (e.g., `/api/hello/world`).\n\n## HTTP Methods\n\nSuffix your file with the HTTP method (`.get.ts`, `.post.ts`, `.put.ts`, `.delete.ts`, etc.):\n\n### GET Handler\n\n```ts [api/test.get.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Test get handler\");\n```\n\n### POST Handler\n\n```ts [api/test.post.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const body = await event.req.json();\n  return {\n    message: \"Test post handler\",\n    body,\n  };\n});\n```\n"
  },
  {
    "path": "examples/api-routes/api/hello/[name].ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => `Hello (param: ${event.context.params!.name})!`);\n"
  },
  {
    "path": "examples/api-routes/api/hello.ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n"
  },
  {
    "path": "examples/api-routes/api/test.get.ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Test get handler\");\n"
  },
  {
    "path": "examples/api-routes/api/test.post.ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler(async (event) => {\n  const body = await event.req.json();\n  return {\n    message: \"Test post handler\",\n    body,\n  };\n});\n"
  },
  {
    "path": "examples/api-routes/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <title>API Routes</title>\n  </head>\n  <body>\n    <h2>API Routes:</h2>\n    <ul>\n      <li><a href=\"/api/hello\">/api/hello</a></li>\n      <li><a href=\"/api/hello/world\">/api/hello/world</a></li>\n      <li><a href=\"/api/test\">/api/test</a></li>\n    </ul>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/api-routes/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n});\n"
  },
  {
    "path": "examples/api-routes/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/api-routes/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/api-routes/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/auto-imports/README.md",
    "content": "Functions exported from `server/utils/` are automatically available without explicit imports when auto-imports are enabled. Define a utility once and use it anywhere in your server code.\n\n## Configuration\n\nEnable auto-imports by setting `imports` in your config:\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n  imports: {},\n});\n```\n\n## Using Auto Imports\n\n1. Create a utility file in `server/utils/`:\n\n```ts [server/utils/hello.ts]\nexport function makeGreeting(name: string) {\n  return `Hello, ${name}!`;\n}\n```\n\n2. The function is available without importing it:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { makeGreeting } from \"./server/utils/hello.ts\";\n\nexport default defineHandler(() => `<h1>${makeGreeting(\"Nitro\")}</h1>`);\n```\n\nWith this setup, any function exported from `server/utils/` becomes globally available. Nitro scans the directory and generates the necessary imports automatically.\n"
  },
  {
    "path": "examples/auto-imports/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n  imports: {},\n});\n"
  },
  {
    "path": "examples/auto-imports/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/auto-imports/server/utils/hello.ts",
    "content": "export function makeGreeting(name: string) {\n  return `Hello, ${name}!`;\n}\n"
  },
  {
    "path": "examples/auto-imports/server.ts",
    "content": "import { defineHandler } from \"nitro\";\nimport { makeGreeting } from \"./server/utils/hello.ts\";\n\nexport default defineHandler(() => `<h1>${makeGreeting(\"Nitro\")}</h1>`);\n"
  },
  {
    "path": "examples/auto-imports/tsconfig.json",
    "content": "{\n  \"include\": [\".nitro/types/nitro-imports.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "examples/auto-imports/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/cached-handler/README.md",
    "content": "This example shows how to cache an expensive operation (a 500 ms delay) and conditionally bypass the cache using a query parameter. On first request, the handler executes and caches the result. Subsequent requests return the cached response instantly until the cache expires or is bypassed.\n\n## How It Works\n\n```ts [server.ts]\nimport { html } from \"nitro\";\nimport { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler(\n  async () => {\n    await new Promise((resolve) => setTimeout(resolve, 500));\n    return html`\n      Response generated at ${new Date().toISOString()} (took 500ms)\n      <br />(<a href=\"?skipCache=true\">skip cache</a>)\n    `;\n  },\n  { shouldBypassCache: ({ req }) => req.url.includes(\"skipCache=true\") }\n);\n```\n\nThe handler simulates a slow operation with a 500ms delay. As `defineCachedHandler` wraps it, the response is cached after the first execution. The `shouldBypassCache` option checks for `?skipCache=true` in the URL and when present the cache is skipped and the handler runs fresh.\n"
  },
  {
    "path": "examples/cached-handler/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/cached-handler/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/cached-handler/server.ts",
    "content": "import { html } from \"nitro\";\nimport { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler(\n  async () => {\n    await new Promise((resolve) => setTimeout(resolve, 500));\n    return html`\n      Response generated at ${new Date().toISOString()} (took 500ms)\n      <br />(<a href=\"?skipCache=true\">skip cache</a>)\n    `;\n  },\n  { shouldBypassCache: ({ req }) => req.url.includes(\"skipCache=true\") }\n);\n"
  },
  {
    "path": "examples/cached-handler/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/cached-handler/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/custom-error-handler/README.md",
    "content": "This example shows how to intercept all errors and return a custom response format. When any route throws an error, Nitro calls your error handler instead of returning the default error page.\n\n## Error Handler\n\nCreate an `error.ts` file in your project root to define the global error handler:\n\n```ts [error.ts]\nimport { defineErrorHandler } from \"nitro\";\n\nexport default defineErrorHandler((error, _event) => {\n  return new Response(`Custom Error Handler: ${error.message}`, {\n    status: 500,\n    headers: { \"Content-Type\": \"text/plain\" },\n  });\n});\n```\n\nThe handler receives the thrown error and the H3 event object. You can use the event to access request details like headers, cookies, or the URL path to customize responses per route.\n\n## Triggering an Error\n\nThe main handler throws an error to demonstrate the custom error handler:\n\n```ts [server.ts]\nimport { defineHandler, HTTPError } from \"nitro\";\n\nexport default defineHandler(() => {\n  throw new HTTPError(\"Example Error!\", { status: 500 });\n});\n```\n\nWhen you visit the page, instead of seeing a generic error page, you'll see \"Custom Error Handler: Example Error!\" because the error handler intercepts the thrown error.\n"
  },
  {
    "path": "examples/custom-error-handler/error.ts",
    "content": "import { defineErrorHandler } from \"nitro\";\n\nexport default defineErrorHandler((error, _event) => {\n  return new Response(`Custom Error Handler: ${error.message}`, {\n    status: 500,\n    headers: { \"Content-Type\": \"text/plain\" },\n  });\n});\n"
  },
  {
    "path": "examples/custom-error-handler/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n// import errorHandler from \"./error\";\n\nexport default defineConfig({\n  errorHandler: \"./error.ts\",\n  // devErrorHandler: errorHandler,\n});\n"
  },
  {
    "path": "examples/custom-error-handler/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/custom-error-handler/server.ts",
    "content": "import { defineHandler, HTTPError } from \"nitro\";\n\nexport default defineHandler(() => {\n  throw new HTTPError(\"Example Error!\", { status: 500 });\n});\n"
  },
  {
    "path": "examples/custom-error-handler/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/custom-error-handler/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/database/README.md",
    "content": "Nitro provides a built-in database layer that uses SQL template literals for safe, parameterized queries. This example creates a users table, inserts a record, and queries it back.\n\n## Querying the Database\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineHandler(async () => {\n  const db = useDatabase();\n\n  // Create users table\n  await db.sql`DROP TABLE IF EXISTS users`;\n  await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n  // Add a new user\n  const userId = String(Math.round(Math.random() * 10_000));\n  await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;\n\n  // Query for users\n  const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\n\n  return {\n    rows,\n  };\n});\n```\n\nRetrieve the database instance using `useDatabase()`. The database can be queried using `db.sql`, and variables like `${userId}` are automatically escaped to prevent SQL injection.\n\n## Running Migrations with Tasks\n\nNitro tasks let you run operations outside of request handlers. For database migrations, create a task file in `tasks/` and run it via the CLI. This keeps schema changes separate from your application code.\n\n```ts [tasks/db/migrate.ts]\nimport { defineTask } from \"nitro/task\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineTask({\n  meta: {\n    description: \"Run database migrations\",\n  },\n  async run() {\n    const db = useDatabase();\n\n    console.log(\"Running database migrations...\");\n\n    // Create users table\n    await db.sql`DROP TABLE IF EXISTS users`;\n    await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n    return {\n      result: \"Database migrations complete!\",\n    };\n  },\n});\n```\n"
  },
  {
    "path": "examples/database/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  experimental: {\n    database: true,\n    tasks: true,\n  },\n  database: {\n    default: { connector: \"sqlite\" },\n  },\n});\n"
  },
  {
    "path": "examples/database/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/database/server.ts",
    "content": "import { defineHandler } from \"nitro\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineHandler(async () => {\n  const db = useDatabase();\n\n  // Create users table\n  await db.sql`DROP TABLE IF EXISTS users`;\n  await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n  // Add a new user\n  const userId = String(Math.round(Math.random() * 10_000));\n  await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;\n\n  // Query for users\n  const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\n\n  return {\n    rows,\n  };\n});\n"
  },
  {
    "path": "examples/database/tasks/db/migrate.ts",
    "content": "import { defineTask } from \"nitro/task\";\nimport { useDatabase } from \"nitro/database\";\n\nexport default defineTask({\n  meta: {\n    description: \"Run database migrations\",\n  },\n  async run() {\n    const db = useDatabase();\n\n    console.log(\"Running database migrations...\");\n\n    // Create users table\n    await db.sql`DROP TABLE IF EXISTS users`;\n    await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n    return {\n      result: \"Database migrations complete!\",\n    };\n  },\n});\n"
  },
  {
    "path": "examples/database/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/database/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/elysia/README.md",
    "content": "## Server Entry\n\n```ts [server.ts]\nimport { Elysia } from \"elysia\";\n\nconst app = new Elysia();\n\napp.get(\"/\", () => \"Hello, Elysia with Nitro!\");\n\nexport default app.compile();\n```\n\nNitro auto-detects `server.ts` in your project root and uses it as the server entry. The Elysia app handles all incoming requests, giving you full control over routing and middleware.\n\nCall `app.compile()` before exporting to optimize the router for production.\n"
  },
  {
    "path": "examples/elysia/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/elysia/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"elysia\": \"^1.4.28\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/elysia/server.ts",
    "content": "import { Elysia } from \"elysia\";\n\nconst app = new Elysia();\n\napp.get(\"/\", () => \"Hello, Elysia with Nitro!\");\n\nexport default app.compile();\n"
  },
  {
    "path": "examples/elysia/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/elysia/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/express/README.md",
    "content": "## Server Entry\n\n```ts [server.node.ts]\nimport Express from \"express\";\n\nconst app = Express();\n\napp.use(\"/\", (_req, res) => {\n  res.send(\"Hello from Express with Nitro!\");\n});\n\nexport default app;\n```\n\nNitro auto-detects `server.node.ts` in your project root and uses it as the server entry. The Express app handles all incoming requests, giving you full control over routing and middleware.\n\n::note\nThe `.node.ts` suffix indicates this entry is Node.js specific and won't work in other runtimes like Cloudflare Workers or Deno.\n::\n"
  },
  {
    "path": "examples/express/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/express/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^5.0.6\",\n    \"express\": \"^5.2.1\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/express/server.node.ts",
    "content": "import Express from \"express\";\n\nconst app = Express();\n\napp.use(\"/\", (_req, res) => {\n  res.send(\"Hello from Express with Nitro!\");\n});\n\nexport default app;\n"
  },
  {
    "path": "examples/express/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/express/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/fastify/README.md",
    "content": "## Server Entry\n\n```ts [server.node.ts]\nimport Fastify from \"fastify\";\n\nconst app = Fastify();\n\napp.get(\"/\", () => \"Hello, Fastify with Nitro!\");\n\nawait app.ready();\n\nexport default app.routing;\n```\n\nNitro auto-detects `server.node.ts` in your project root and uses it as the server entry.\n\nCall `await app.ready()` to initialize all registered plugins before exporting. Export `app.routing` (not `app`) to provide Nitro with the request handler function.\n\n::note\nThe `.node.ts` suffix indicates this entry is Node.js specific and won't work in other runtimes like Cloudflare Workers or Deno.\n::\n"
  },
  {
    "path": "examples/fastify/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/fastify/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"fastify\": \"^5.8.2\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/fastify/server.node.ts",
    "content": "import Fastify from \"fastify\";\n\nconst app = Fastify();\n\napp.get(\"/\", () => \"Hello, Fastify with Nitro!\");\n\nawait app.ready();\n\nexport default app.routing;\n"
  },
  {
    "path": "examples/fastify/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/fastify/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/hello-world/README.md",
    "content": "The simplest Nitro server. Export an object with a `fetch` method that receives a standard `Request` and returns a `Response`. No frameworks, no abstractions, just the web platform.\n\n\n## Server Entry\n\n```ts [server.ts]\nexport default {\n  fetch(req: Request) {\n    return new Response(\"Nitro Works!\");\n  },\n};\n```\n\nThe `fetch` method follows the same signature as Service Workers and Cloudflare Workers. This pattern works across all deployment targets because it uses web standards.\n\nAdd the Nitro plugin to Vite and it handles the rest: dev server, hot reloading, and production builds.\n"
  },
  {
    "path": "examples/hello-world/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/hello-world/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\",\n    \"preview\": \"node .output/server/index.mjs\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/hello-world/server.ts",
    "content": "export default {\n  fetch(req: Request) {\n    return new Response(\"Nitro Works!\");\n  },\n};\n"
  },
  {
    "path": "examples/hello-world/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/hello-world/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/hono/README.md",
    "content": "## Server Entry\n\n```ts [server.ts]\nimport { Hono } from \"hono\";\n\nconst app = new Hono();\n\napp.get(\"/\", (c) => {\n  return c.text(\"Hello, Hono with Nitro!\");\n});\n\nexport default app;\n```\n\nNitro auto-detects `server.ts` in your project root and uses it as the server entry. The Hono app handles all incoming requests, giving you full control over routing and middleware.\n\nHono is cross-runtime compatible, so this server entry works across all Nitro deployment targets including Node.js, Deno, Bun, and Cloudflare Workers.\n"
  },
  {
    "path": "examples/hono/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/hono/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"hono\": \"^4.12.8\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/hono/server.ts",
    "content": "import { Hono } from \"hono\";\n\nconst app = new Hono();\n\napp.get(\"/\", (c) => {\n  return c.text(\"Hello, Hono with Nitro!\");\n});\n\nexport default app;\n"
  },
  {
    "path": "examples/hono/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/hono/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/import-alias/README.md",
    "content": "Import aliases like `~` and `#` let you reference modules with shorter paths instead of relative imports.\n\n## Importing Using Aliases\n\n```ts [server/routes/index.ts]\nimport { sum } from \"~server/utils/math.ts\";\n\nimport { rand } from \"#server/utils/math.ts\";\n\nexport default () => {\n  const [a, b] = [rand(1, 10), rand(1, 10)];\n  const result = sum(a, b);\n  return `The sum of ${a} + ${b} = ${result}`;\n};\n```\n\nThe route imports the `sum` function using `~server/` and `rand` using `#server/`. Both resolve to the same `server/utils/math.ts` file. The handler generates two random numbers and returns their sum.\n\n## Configuration\n\nAliases can be configured in `package.json` imports field or `nitro.config.ts`.\n"
  },
  {
    "path": "examples/import-alias/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n});\n"
  },
  {
    "path": "examples/import-alias/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"imports\": {\n    \"#server/*\": \"./server/*\"\n  },\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\",\n    \"preview\": \"node .output/server/index.mjs\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/import-alias/server/routes/index.ts",
    "content": "import { sum } from \"~server/utils/math.ts\";\n\nimport { rand } from \"#server/utils/math.ts\";\n\nexport default () => {\n  const [a, b] = [rand(1, 10), rand(1, 10)];\n  const result = sum(a, b);\n  return `The sum of ${a} + ${b} = ${result}`;\n};\n"
  },
  {
    "path": "examples/import-alias/server/utils/math.ts",
    "content": "export function rand(min: number, max: number): number {\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nexport function sum(a: number, b: number): number {\n  return a + b;\n}\n"
  },
  {
    "path": "examples/import-alias/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"paths\": {\n      \"~server/*\": [\"./server/*\"]\n    }\n  }\n}\n"
  },
  {
    "path": "examples/import-alias/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()], resolve: { tsconfigPaths: true } });\n"
  },
  {
    "path": "examples/middleware/README.md",
    "content": "Middleware functions run before route handlers on every request. They can modify the request, add context, or return early responses.\n\n## Defining Middleware\n\nCreate files in `server/middleware/`. They run in alphabetical order:\n\n```ts [server/middleware/auth.ts]\nimport { defineMiddleware } from \"nitro\";\n\nexport default defineMiddleware((event) => {\n  event.context.auth = { name: \"User \" + Math.round(Math.random() * 100) };\n});\n```\n\nMiddleware can:\n- Add data to `event.context` for use in handlers\n- Return a response early to short-circuit the request\n- Modify request headers or other properties\n\n## Accessing Context in Handlers\n\nData added to `event.context` in middleware is available in all subsequent handlers:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => ({\n  auth: event.context.auth,\n}));\n```\n"
  },
  {
    "path": "examples/middleware/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n});\n"
  },
  {
    "path": "examples/middleware/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/middleware/server/middleware/auth.ts",
    "content": "import { defineMiddleware } from \"nitro\";\n\nexport default defineMiddleware((event) => {\n  event.context.auth = { name: \"User \" + Math.round(Math.random() * 100) };\n});\n"
  },
  {
    "path": "examples/middleware/server.ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler((event) => ({\n  auth: event.context.auth,\n}));\n"
  },
  {
    "path": "examples/middleware/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/middleware/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/mono-jsx/README.md",
    "content": "## Server Entry\n\n```tsx [server.tsx]\nexport default () => (\n  <html>\n    <h1>Nitro + mono-jsx works!</h1>\n  </html>\n);\n```\n\nNitro auto-detects `server.tsx` and uses mono-jsx to transform JSX into HTML. Export a function that returns JSX, and Nitro sends the rendered HTML as the response.\n"
  },
  {
    "path": "examples/mono-jsx/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/mono-jsx/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"mono-jsx\": \"latest\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/mono-jsx/server.tsx",
    "content": "export default () => (\n  <html>\n    <h1>Nitro + mono-jsx works!</h1>\n  </html>\n);\n"
  },
  {
    "path": "examples/mono-jsx/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"mono-jsx\"\n  }\n}\n"
  },
  {
    "path": "examples/mono-jsx/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/nano-jsx/README.md",
    "content": "## Server Entry\n\n```tsx [server.tsx]\nimport { defineHandler, html } from \"nitro\";\nimport { renderSSR } from \"nano-jsx\";\n\nexport default defineHandler(() => {\n  return html(renderSSR(() => <h1>Nitro + nano-jsx works!</h1>));\n});\n```\n\nNitro auto-detects `server.tsx` and uses it as the server entry. Use `renderSSR` from nano-jsx to convert JSX into an HTML string. The `html` helper from H3 sets the correct content type header.\n"
  },
  {
    "path": "examples/nano-jsx/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({});\n"
  },
  {
    "path": "examples/nano-jsx/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nano-jsx\": \"^0.2.1\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/nano-jsx/server.tsx",
    "content": "import { defineHandler, html } from \"nitro\";\nimport { renderSSR } from \"nano-jsx\";\n\nexport default defineHandler(() => {\n  return html(renderSSR(() => <h1>Nitro + nano-jsx works!</h1>));\n});\n"
  },
  {
    "path": "examples/nano-jsx/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"nano-jsx/esm\"\n  }\n}\n"
  },
  {
    "path": "examples/nano-jsx/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/plugins/README.md",
    "content": "Plugins let you hook into Nitro's runtime lifecycle. This example shows a plugin that modifies the `Content-Type` header on every response. Create files in `server/plugins/` and they're automatically loaded at startup.\n\n## Defining a Plugin\n\n```ts [server/plugins/test.ts]\nimport { definePlugin } from \"nitro\";\nimport { useNitroHooks } from \"nitro/app\";\n\nexport default definePlugin((nitroApp) => {\n  const hooks = useNitroHooks();\n  hooks.hook(\"response\", (event) => {\n    event.headers.set(\"content-type\", \"html; charset=utf-8\");\n  });\n});\n```\n\nThe plugin uses `useNitroHooks()` to access the hooks system, then registers a `response` hook that runs after every request. Here it sets the content type to HTML, but you could log requests, add security headers, or modify responses in any way.\n\n## Main Handler\n\n```ts [server.ts]\nimport { eventHandler } from \"h3\";\n\nexport default eventHandler(() => \"<h1>Hello Nitro!</h1>\");\n```\n\nThe handler returns HTML without setting a content type. The plugin automatically adds the correct `Content-Type: html; charset=utf-8` header to the response.\n"
  },
  {
    "path": "examples/plugins/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: true,\n});\n"
  },
  {
    "path": "examples/plugins/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/plugins/server/plugins/test.ts",
    "content": "import { definePlugin } from \"nitro\";\nimport { useNitroHooks } from \"nitro/app\";\n\nexport default definePlugin((nitroApp) => {\n  const hooks = useNitroHooks();\n  hooks.hook(\"response\", (event) => {\n    event.headers.set(\"content-type\", \"html; charset=utf-8\");\n  });\n});\n"
  },
  {
    "path": "examples/plugins/server.ts",
    "content": "import { eventHandler } from \"h3\";\n\nexport default eventHandler(() => \"<h1>Hello Nitro!</h1>\");\n"
  },
  {
    "path": "examples/plugins/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/plugins/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/renderer/README.md",
    "content": "Create a custom renderer that generates HTML responses with data from API routes. Use Nitro's internal `fetch` to call routes without network overhead.\n\n## Renderer\n\n```ts [renderer.ts]\nimport { fetch } from \"nitro\";\n\nexport default async function renderer({ url }: { req: Request; url: URL }) {\n  const apiRes = await fetch(\"/api/hello\").then((res) => res.text());\n  return new Response(\n    /* html */ `<!DOCTYPE html>\n    <html>\n    <head>\n      <title>Custom Renderer</title>\n    </head>\n    <body>\n      <h1>Hello from custom renderer!</h1>\n      <p>Current path: ${url.pathname}</p>\n      <p>API says: ${apiRes}</p>\n    </body>\n    </html>`,\n    { headers: { \"content-type\": \"text/html; charset=utf-8\" } }\n  );\n}\n```\n\nNitro auto-detects `renderer.ts` in your project root and uses it for all non-API routes. The renderer function receives the request URL and returns a `Response`.\n\nUse `fetch` from `nitro` to call API routes without network overhead—these requests stay in-process.\n\n## API Route\n\n```ts [api/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n```\n\nDefine API routes in the `api/` directory. When the renderer calls `fetch(\"/api/hello\")`, this handler runs and returns its response.\n"
  },
  {
    "path": "examples/renderer/api/hello.ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Nitro is amazing!\");\n"
  },
  {
    "path": "examples/renderer/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  renderer: { handler: \"./renderer\" },\n});\n"
  },
  {
    "path": "examples/renderer/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/renderer/renderer.ts",
    "content": "import { fetch } from \"nitro\";\n\nexport default async function renderer({ url }: { req: Request; url: URL }) {\n  const apiRes = await fetch(\"/api/hello\").then((res) => res.text());\n  return new Response(\n    /* html */ `<!DOCTYPE html>\n    <html>\n    <head>\n      <title>Custom Renderer</title>\n    </head>\n    <body>\n      <h1>Hello from custom renderer!</h1>\n      <p>Current path: ${url.pathname}</p>\n      <p>API says: ${apiRes}</p>\n    </body>\n    </html>`,\n    { headers: { \"content-type\": \"text/html; charset=utf-8\" } }\n  );\n}\n"
  },
  {
    "path": "examples/renderer/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/renderer/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/runtime-config/.env",
    "content": "# NEVER COMMIT SENSITIVE DATA. THIS IS ONLY FOR DEMO PURPOSES.\nNITRO_API_KEY=secret-api-key\n"
  },
  {
    "path": "examples/runtime-config/.gitignore",
    "content": "# THIS IS ONLY FOR DEMO. DO NOT COMMIT SENSITIVE DATA IN REAL PROJECTS\n!.env\n"
  },
  {
    "path": "examples/runtime-config/README.md",
    "content": "Runtime config lets you define configuration values that can be overridden by environment variables at runtime.\n\n## Define Config Schema\n\nDeclare your runtime config with default values in `nitro.config.ts`:\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  runtimeConfig: {\n    apiKey: \"\",\n  },\n});\n```\n\n## Access at Runtime\n\nUse `useRuntimeConfig` to access configuration values in your handlers:\n\n```ts [server.ts]\nimport { defineHandler } from \"nitro\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n  return { runtimeConfig };\n});\n```\n\n## Environment Variables\n\nOverride config values via environment variables prefixed with `NITRO_`:\n\n```sh [.env]\n# NEVER COMMIT SENSITIVE DATA. THIS IS ONLY FOR DEMO PURPOSES.\nNITRO_API_KEY=secret-api-key\n```\n"
  },
  {
    "path": "examples/runtime-config/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  runtimeConfig: {\n    apiKey: \"\",\n  },\n});\n"
  },
  {
    "path": "examples/runtime-config/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/runtime-config/server.ts",
    "content": "import { defineHandler } from \"nitro\";\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n  return { runtimeConfig };\n});\n"
  },
  {
    "path": "examples/runtime-config/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/runtime-config/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/server-fetch/README.md",
    "content": "When you need one route to call another, use Nitro's `fetch` function instead of the global fetch. It makes internal requests that stay in-process, avoiding network round-trips. The request never leaves the server.\n\n## Main Route\n\n```ts [routes/index.ts]\nimport { defineHandler } from \"nitro\";\nimport { fetch } from \"nitro\";\n\nexport default defineHandler(() => fetch(\"/hello\"));\n```\n\nThe index route imports `fetch` from `nitro` (not the global fetch) and calls the `/hello` route. This request is handled internally without going through the network stack.\n\n## Internal API Route\n\n```ts [routes/hello.ts]\nimport { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Hello!\");\n```\n\nA simple route that returns \"Hello!\". When the index route calls `fetch(\"/hello\")`, this handler runs and its response is returned directly.\n"
  },
  {
    "path": "examples/server-fetch/nitro.config.ts",
    "content": "import { defineConfig, serverFetch } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  hooks: {\n    \"dev:start\": async () => {\n      const res = await serverFetch(\"/hello\");\n      const text = await res.text();\n      console.log(\"Fetched /hello in nitro module:\", res.status, text);\n    },\n  },\n});\n"
  },
  {
    "path": "examples/server-fetch/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/server-fetch/routes/hello.ts",
    "content": "import { defineHandler } from \"nitro\";\n\nexport default defineHandler(() => \"Hello!\");\n"
  },
  {
    "path": "examples/server-fetch/routes/index.ts",
    "content": "import { defineHandler } from \"nitro\";\nimport { fetch } from \"nitro\";\n\nexport default defineHandler(() => fetch(\"/hello\"));\n"
  },
  {
    "path": "examples/server-fetch/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/server-fetch/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/shiki/README.md",
    "content": "Use Shiki for syntax highlighting with TextMate grammars. This example highlights code on the server using Nitro's server scripts feature, which runs JavaScript inside HTML files before sending the response.\n\n## API Route\n\n```ts [api/highlight.ts]\nimport { createHighlighterCore } from \"shiki/core\";\nimport { createOnigurumaEngine } from \"shiki/engine/oniguruma\";\n\nconst highlighter = await createHighlighterCore({\n  engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n  themes: [await import(\"shiki/themes/vitesse-dark.mjs\")],\n  langs: [await import(\"shiki/langs/ts.mjs\")],\n});\n\nexport default async ({ req }: { req: Request }) => {\n  const code = await req.text();\n  const html = await highlighter.codeToHtml(code, {\n    lang: \"ts\",\n    theme: \"vitesse-dark\",\n  });\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n  });\n};\n```\n\nCreate a Shiki highlighter with the Vitesse Dark theme and TypeScript language support. When the API receives a POST request, it reads the code from the request body and returns highlighted HTML.\n\n## Server-Side Rendering\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <title>Hello World Snippet</title>\n    <link rel=\"stylesheet\" href=\"styles.css\" />\n  </head>\n  <body>\n    <div class=\"card\" role=\"region\" aria-label=\"Code snippet\">\n      <div class=\"label\">JavaScript</div>\n      <script server>\n        const hl = (code) =>\n          serverFetch(\"/api/highlight\", {\n            method: \"POST\",\n            body: code,\n          });\n      </script>\n      <pre><code>{{{ hl(`console.log(\"💚 Simple is beautiful!\");`) }}}</code></pre>\n    </div>\n  </body>\n</html>\n```\n\nThe `<script server>` tag runs on the server before the HTML is sent. It defines a helper function that calls the highlight API using `serverFetch`. The triple-brace syntax `{{{ }}}` outputs the result without escaping, so the highlighted HTML renders correctly.\n"
  },
  {
    "path": "examples/shiki/api/highlight.ts",
    "content": "import { createHighlighterCore } from \"shiki/core\";\nimport { createOnigurumaEngine } from \"shiki/engine/oniguruma\";\n\nconst highlighter = await createHighlighterCore({\n  engine: createOnigurumaEngine(import(\"shiki/wasm\")),\n  themes: [await import(\"shiki/themes/vitesse-dark.mjs\")],\n  langs: [await import(\"shiki/langs/ts.mjs\")],\n});\n\nexport default async ({ req }: { req: Request }) => {\n  const code = await req.text();\n  const html = await highlighter.codeToHtml(code, {\n    lang: \"ts\",\n    theme: \"vitesse-dark\",\n  });\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html; charset=utf-8\" },\n  });\n};\n"
  },
  {
    "path": "examples/shiki/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n    <title>Hello World Snippet</title>\n    <link rel=\"stylesheet\" href=\"styles.css\" />\n  </head>\n  <body>\n    <div class=\"card\" role=\"region\" aria-label=\"Code snippet\">\n      <div class=\"label\">JavaScript</div>\n      <script server>\n        const hl = (code) =>\n          serverFetch(\"/api/highlight\", {\n            method: \"POST\",\n            body: code,\n          });\n      </script>\n      <pre><code>{{{ hl(`console.log(\"💚 Simple is beautiful!\");`) }}}</code></pre>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/shiki/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n});\n"
  },
  {
    "path": "examples/shiki/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite dev\",\n    \"build\": \"vite build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"shiki\": \"^3.23.0\"\n  }\n}\n"
  },
  {
    "path": "examples/shiki/styles.css",
    "content": "html,\nbody {\n  height: 100%;\n  margin: 0;\n}\nbody {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background: #f6f8fa;\n  font-family:\n    system-ui,\n    -apple-system,\n    \"Segoe UI\",\n    Roboto,\n    \"Helvetica Neue\",\n    Arial,\n    \"Noto Sans\",\n    \"Liberation Sans\",\n    sans-serif;\n}\n.card {\n  text-align: left;\n  background: #0b1220;\n  color: #e6edf3;\n  padding: 1rem;\n  border-radius: 8px;\n  box-shadow: 0 8px 24px rgba(2, 6, 23, 0.2);\n  max-width: 90%;\n  width: 520px;\n}\n.label {\n  font-size: 12px;\n  color: #9aa7b2;\n  margin-bottom: 8px;\n}\npre {\n  margin: 0;\n  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, \"Courier New\", monospace;\n  font-size: 14px;\n  background: transparent;\n  white-space: pre;\n  overflow: auto;\n}\n"
  },
  {
    "path": "examples/shiki/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/shiki/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n"
  },
  {
    "path": "examples/virtual-routes/README.md",
    "content": "Virtual routes let you define handlers as strings in your config instead of creating separate files. This is useful when generating routes dynamically, building plugins, or keeping simple routes inline.\n\n## Configuration\n\n```ts [nitro.config.ts]\nimport { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  routes: {\n    \"/\": \"#virtual-route\",\n  },\n  virtual: {\n    \"#virtual-route\": () =>\n      /* js */ `export default () => new Response(\"Hello from virtual entry!\")`,\n  },\n});\n```\n\nThe `routes` option maps URL paths to virtual module identifiers (prefixed with `#`). The `virtual` option defines the module content as a string or function returning a string. At build time, Nitro resolves these virtual modules to actual handlers.\n\nThere are no route files in this project. The entire handler is defined inline in the config, and Nitro generates the route at build time.\n"
  },
  {
    "path": "examples/virtual-routes/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  routes: {\n    \"/\": \"#virtual-route\",\n  },\n  virtual: {\n    \"#virtual-route\": () =>\n      /* js */ `export default () => new Response(\"Hello from virtual entry!\")`,\n  },\n});\n"
  },
  {
    "path": "examples/virtual-routes/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"dev\": \"nitro dev\",\n    \"preview\": \"node .output/server/index.mjs\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/virtual-routes/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/virtual-routes/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "examples/vite-nitro-plugin/README.md",
    "content": "Instead of using a separate `nitro.config.ts`, you can configure Nitro directly in your Vite config. This gives you access to Nitro's setup hook where you can register routes and virtual modules programmatically.\n\n## Vite Configuration\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro(),\n    {\n      name: \"my-nitro-plugin\",\n      nitro: {\n        setup: (nitro) => {\n          nitro.options.routes[\"/\"] = \"#virtual-by-plugin\";\n          nitro.options.virtual[\"#virtual-by-plugin\"] =\n            `export default () => new Response(\"Hello from virtual entry!\")`;\n        },\n      },\n    },\n  ],\n});\n```\n\nThe config adds two plugins: the `nitro()` plugin and a custom plugin that uses the `nitro.setup` hook. Inside the setup function, you have access to Nitro's options object. This example registers a virtual route at `/` that maps to a virtual module `#virtual-by-plugin`, then defines that module inline.\n"
  },
  {
    "path": "examples/vite-nitro-plugin/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-nitro-plugin/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/vite-nitro-plugin/vite.config.mjs",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro(),\n    {\n      name: \"my-nitro-plugin\",\n      nitro: {\n        setup: (nitro) => {\n          nitro.options.routes[\"/\"] = \"#virtual-by-plugin\";\n          nitro.options.virtual[\"#virtual-by-plugin\"] =\n            `export default () => new Response(\"Hello from virtual entry!\")`;\n        },\n      },\n    },\n  ],\n});\n"
  },
  {
    "path": "examples/vite-rsc/.gitignore",
    "content": "node_modules\ndist\n"
  },
  {
    "path": "examples/vite-rsc/README.md",
    "content": "This example demonstrates React Server Components (RSC) using Vite's experimental RSC plugin with Nitro. It includes server components, client components, server actions, and streaming SSR.\n\n## Overview\n\n1. **SSR Entry** handles incoming requests and renders React components to HTML\n2. **Root Component** defines the page structure as a server component\n3. **Client Components** use the `\"use client\"` directive for interactive parts\n\n## 1. SSR Entry\n\n```tsx [app/framework/entry.ssr.tsx]\nimport { createFromReadableStream } from \"@vitejs/plugin-rsc/ssr\";\nimport React from \"react\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { injectRSCPayload } from \"rsc-html-stream/server\";\nimport type { RscPayload } from \"./entry.rsc\";\n\nexport default {\n  fetch: async (request: Request) => {\n    const rscEntryModule = await import.meta.viteRsc.loadModule<typeof import(\"./entry.rsc\")>(\n      \"rsc\",\n      \"index\"\n    );\n    return rscEntryModule.default(request);\n  },\n};\n\nexport async function renderHTML(\n  rscStream: ReadableStream<Uint8Array>,\n  options: {\n    formState?: ReactFormState;\n    nonce?: string;\n    debugNoJS?: boolean;\n  }\n): Promise<{ stream: ReadableStream<Uint8Array>; status?: number }> {\n  // Duplicate one RSC stream into two.\n  // - one for SSR (ReactClient.createFromReadableStream below)\n  // - another for browser hydration payload by injecting <script>...FLIGHT_DATA...</script>.\n  const [rscStream1, rscStream2] = rscStream.tee();\n\n  // Deserialize RSC stream back to React VDOM\n  let payload: Promise<RscPayload> | undefined;\n  function SsrRoot() {\n    // Deserialization needs to be kicked off inside ReactDOMServer context\n    // for ReactDOMServer preinit/preloading to work\n    payload ??= createFromReadableStream<RscPayload>(rscStream1);\n    return React.use(payload).root;\n  }\n\n  // Render HTML (traditional SSR)\n  const bootstrapScriptContent = await import.meta.viteRsc.loadBootstrapScriptContent(\"index\");\n\n  let htmlStream: ReadableStream<Uint8Array>;\n  let status: number | undefined;\n\n  try {\n    htmlStream = await renderToReadableStream(<SsrRoot />, {\n      bootstrapScriptContent: options?.debugNoJS ? undefined : bootstrapScriptContent,\n      nonce: options?.nonce,\n      formState: options?.formState,\n    });\n  } catch {\n    // fallback to render an empty shell and run pure CSR on browser,\n    // which can replay server component error and trigger error boundary.\n    status = 500;\n    htmlStream = await renderToReadableStream(\n      <html>\n        <body>\n          <noscript>Internal Server Error: SSR failed</noscript>\n        </body>\n      </html>,\n      {\n        bootstrapScriptContent:\n          `self.__NO_HYDRATE=1;` + (options?.debugNoJS ? \"\" : bootstrapScriptContent),\n        nonce: options?.nonce,\n      }\n    );\n  }\n\n  let responseStream: ReadableStream<Uint8Array> = htmlStream;\n  if (!options?.debugNoJS) {\n    // Initial RSC stream is injected in HTML stream as <script>...FLIGHT_DATA...</script>\n    // using utility made by devongovett https://github.com/devongovett/rsc-html-stream\n    responseStream = responseStream.pipeThrough(\n      injectRSCPayload(rscStream2, {\n        nonce: options?.nonce,\n      })\n    );\n  }\n\n  return { stream: responseStream, status };\n}\n```\n\nThe SSR entry handles the rendering pipeline. It loads the RSC entry module, duplicates the RSC stream (one for SSR, one for hydration), deserializes the stream back to React VDOM, and renders it to HTML. The RSC payload is injected into the HTML for client hydration.\n\n## 2. Root Server Component\n\n```tsx [app/root.tsx]\nimport \"./index.css\"; // css import is automatically injected in exported server components\nimport viteLogo from \"./assets/vite.svg\";\nimport { getServerCounter, updateServerCounter } from \"./action.tsx\";\nimport reactLogo from \"./assets/react.svg\";\nimport nitroLogo from \"./assets/nitro.svg\";\nimport { ClientCounter } from \"./client.tsx\";\n\nexport function Root(props: { url: URL }) {\n  return (\n    <html lang=\"en\">\n      <head>\n        {/* eslint-disable-next-line unicorn/text-encoding-identifier-case */}\n        <meta charSet=\"UTF-8\" />\n        <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <title>Nitro + Vite + RSC</title>\n      </head>\n      <body>\n        <App {...props} />\n      </body>\n    </html>\n  );\n}\n\nfunction App(props: { url: URL }) {\n  return (\n    <div id=\"root\">\n      <div>\n        <a href=\"https://vite.dev\" target=\"_blank\">\n          <img src={viteLogo} className=\"logo\" alt=\"Vite logo\" />\n        </a>\n        <a href=\"https://react.dev/reference/rsc/server-components\" target=\"_blank\">\n          <img src={reactLogo} className=\"logo react\" alt=\"React logo\" />\n        </a>\n\n        <a href=\"https://nitro.build\" target=\"_blank\">\n          <img src={nitroLogo} className=\"logo\" alt=\"Nitro logo\" />\n        </a>\n      </div>\n      <h1>Vite + RSC + Nitro</h1>\n      <div className=\"card\">\n        <ClientCounter />\n      </div>\n      <div className=\"card\">\n        <form action={updateServerCounter.bind(null, 1)}>\n          <button>Server Counter: {getServerCounter()}</button>\n        </form>\n      </div>\n      <div className=\"card\">Request URL: {props.url?.href}</div>\n      <ul className=\"read-the-docs\">\n        <li>\n          Edit <code>src/client.tsx</code> to test client HMR.\n        </li>\n        <li>\n          Edit <code>src/root.tsx</code> to test server HMR.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"./_.rsc\" target=\"_blank\">\n            <code>_.rsc</code>\n          </a>{\" \"}\n          to view RSC stream payload.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"?__nojs\" target=\"_blank\">\n            <code>?__nojs</code>\n          </a>{\" \"}\n          to test server action without js enabled.\n        </li>\n      </ul>\n    </div>\n  );\n}\n```\n\nServer components run only on the server. They can import CSS directly, use server-side data, and call server actions. The `ClientCounter` component is imported but runs on the client because it has the `\"use client\"` directive.\n\n## 3. Client Component\n\n```tsx [app/client.tsx]\n\"use client\";\n\nimport React from \"react\";\n\nexport function ClientCounter() {\n  const [count, setCount] = React.useState(0);\n\n  return <button onClick={() => setCount((count) => count + 1)}>Client Counter: {count}</button>;\n}\n```\n\nThe `\"use client\"` directive marks this as a client component. It hydrates on the browser and handles interactive state. Server components can import and render client components, but client components cannot import server components.\n"
  },
  {
    "path": "examples/vite-rsc/app/action.tsx",
    "content": "\"use server\";\n\nlet serverCounter = 0;\n\nexport async function getServerCounter() {\n  return serverCounter;\n}\n\nexport async function updateServerCounter(change: number) {\n  serverCounter += change;\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/client.tsx",
    "content": "\"use client\";\n\nimport React from \"react\";\n\nexport function ClientCounter() {\n  const [count, setCount] = React.useState(0);\n\n  return <button onClick={() => setCount((count) => count + 1)}>Client Counter: {count}</button>;\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/framework/entry.browser.tsx",
    "content": "import {\n  createFromReadableStream,\n  createFromFetch,\n  setServerCallback,\n  createTemporaryReferenceSet,\n  encodeReply,\n} from \"@vitejs/plugin-rsc/browser\";\nimport React from \"react\";\nimport { createRoot, hydrateRoot } from \"react-dom/client\";\nimport { rscStream } from \"rsc-html-stream/client\";\nimport { GlobalErrorBoundary } from \"./error-boundary\";\nimport type { RscPayload } from \"./entry.rsc\";\nimport { createRscRenderRequest } from \"./request\";\n\nasync function main() {\n  // Stash `setPayload` function to trigger re-rendering\n  // from outside of `BrowserRoot` component (e.g. server function call, navigation, hmr)\n  let setPayload: (v: RscPayload) => void;\n\n  // Deserialize RSC stream back to React VDOM for CSR\n  const initialPayload = await createFromReadableStream<RscPayload>(\n    // Initial RSC stream is injected in SSR stream as <script>...FLIGHT_DATA...</script>\n    rscStream\n  );\n\n  // Browser root component to (re-)render RSC payload as state\n  function BrowserRoot() {\n    const [payload, setPayload_] = React.useState(initialPayload);\n\n    React.useEffect(() => {\n      setPayload = (v) => React.startTransition(() => setPayload_(v));\n    }, [setPayload_]);\n\n    // Re-fetch/render on client side navigation\n    React.useEffect(() => {\n      return listenNavigation(() => fetchRscPayload());\n    }, []);\n\n    return payload.root;\n  }\n\n  // Re-fetch RSC and trigger re-rendering\n  async function fetchRscPayload() {\n    const renderRequest = createRscRenderRequest(globalThis.location.href);\n    const payload = await createFromFetch<RscPayload>(fetch(renderRequest));\n    setPayload(payload);\n  }\n\n  // Register a handler which will be internally called by React\n  // on server function request after hydration.\n  setServerCallback(async (id, args) => {\n    const temporaryReferences = createTemporaryReferenceSet();\n    const renderRequest = createRscRenderRequest(globalThis.location.href, {\n      id,\n      body: await encodeReply(args, { temporaryReferences }),\n    });\n    const payload = await createFromFetch<RscPayload>(fetch(renderRequest), {\n      temporaryReferences,\n    });\n    setPayload(payload);\n    const { ok, data } = payload.returnValue!;\n    if (!ok) throw data;\n    return data;\n  });\n\n  // Hydration\n  const browserRoot = (\n    <React.StrictMode>\n      <GlobalErrorBoundary>\n        <BrowserRoot />\n      </GlobalErrorBoundary>\n    </React.StrictMode>\n  );\n  if (\"__NO_HYDRATE\" in globalThis) {\n    createRoot(document).render(browserRoot);\n  } else {\n    hydrateRoot(document, browserRoot, {\n      formState: initialPayload.formState,\n    });\n  }\n\n  // Implement server HMR by triggering re-fetch/render of RSC upon server code change\n  if (import.meta.hot) {\n    import.meta.hot.on(\"rsc:update\", () => {\n      fetchRscPayload();\n    });\n  }\n}\n\n// A little helper to setup events interception for client side navigation\nfunction listenNavigation(onNavigation: () => void) {\n  globalThis.addEventListener(\"popstate\", onNavigation);\n\n  const oldPushState = globalThis.history.pushState;\n  globalThis.history.pushState = function (...args) {\n    const res = oldPushState.apply(this, args);\n    onNavigation();\n    return res;\n  };\n\n  const oldReplaceState = globalThis.history.replaceState;\n  globalThis.history.replaceState = function (...args) {\n    const res = oldReplaceState.apply(this, args);\n    onNavigation();\n    return res;\n  };\n\n  function onClick(e: MouseEvent) {\n    const link = (e.target as Element).closest(\"a\");\n    if (\n      link &&\n      link instanceof HTMLAnchorElement &&\n      link.href &&\n      (!link.target || link.target === \"_self\") &&\n      link.origin === location.origin &&\n      !link.hasAttribute(\"download\") &&\n      e.button === 0 && // left clicks only\n      !e.metaKey && // open in new tab (mac)\n      !e.ctrlKey && // open in new tab (windows)\n      !e.altKey && // download\n      !e.shiftKey &&\n      !e.defaultPrevented\n    ) {\n      e.preventDefault();\n      history.pushState(null, \"\", link.href);\n    }\n  }\n  document.addEventListener(\"click\", onClick);\n\n  return () => {\n    document.removeEventListener(\"click\", onClick);\n    globalThis.removeEventListener(\"popstate\", onNavigation);\n    globalThis.history.pushState = oldPushState;\n    globalThis.history.replaceState = oldReplaceState;\n  };\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain();\n"
  },
  {
    "path": "examples/vite-rsc/app/framework/entry.rsc.tsx",
    "content": "import {\n  renderToReadableStream,\n  createTemporaryReferenceSet,\n  decodeReply,\n  loadServerAction,\n  decodeAction,\n  decodeFormState,\n} from \"@vitejs/plugin-rsc/rsc\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { Root } from \"../root.tsx\";\nimport { parseRenderRequest } from \"./request.tsx\";\n\n// The schema of payload which is serialized into RSC stream on rsc environment\n// and deserialized on ssr/client environments.\nexport type RscPayload = {\n  // this demo renders/serializes/deserializes entire root html element\n  // but this mechanism can be changed to render/fetch different parts of components\n  // based on your own route conventions.\n  root: React.ReactNode;\n\n  // Server action return value of non-progressive enhancement case\n  returnValue?: { ok: boolean; data: unknown };\n\n  // Server action form state (e.g. useActionState) of progressive enhancement case\n  formState?: ReactFormState;\n};\n\n// The plugin by default assumes `rsc` entry having default export of request handler.\n// however, how server entries are executed can be customized by registering own server handler.\nexport default async function handler(request: Request): Promise<Response> {\n  // Differentiate RSC, SSR, action, etc.\n  const renderRequest = parseRenderRequest(request);\n  request = renderRequest.request;\n\n  // Handle server function request\n  let returnValue: RscPayload[\"returnValue\"] | undefined;\n  let formState: ReactFormState | undefined;\n  let temporaryReferences: unknown | undefined;\n  let actionStatus: number | undefined;\n\n  if (renderRequest.isAction === true) {\n    if (renderRequest.actionId) {\n      // Action is called via `ReactClient.setServerCallback`.\n      const contentType = request.headers.get(\"content-type\");\n      const body = contentType?.startsWith(\"multipart/form-data\")\n        ? await request.formData()\n        : await request.text();\n      temporaryReferences = createTemporaryReferenceSet();\n      const args = await decodeReply(body, { temporaryReferences });\n      const action = await loadServerAction(renderRequest.actionId);\n      try {\n        // eslint-disable-next-line prefer-spread\n        const data = await action.apply(null, args);\n        returnValue = { ok: true, data };\n      } catch (error_) {\n        returnValue = { ok: false, data: error_ };\n        actionStatus = 500;\n      }\n    } else {\n      // Otherwise server function is called via `<form action={...}>`\n      // before hydration (e.g. when JavaScript is disabled).\n      // aka progressive enhancement.\n      const formData = await request.formData();\n      const decodedAction = await decodeAction(formData);\n      try {\n        const result = await decodedAction();\n        formState = await decodeFormState(result, formData);\n      } catch {\n        // there's no single general obvious way to surface this error,\n        // so explicitly return classic 500 response.\n        return new Response(\"Internal Server Error: server action failed\", {\n          status: 500,\n        });\n      }\n    }\n  }\n\n  // Serialization from React VDOM tree to RSC stream.\n  // We render RSC stream after handling server function request\n  // so that new render reflects updated state from server function call\n  // to achieve single round trip to mutate and fetch from server.\n  const rscPayload: RscPayload = {\n    root: <Root url={renderRequest.url} />,\n    formState,\n    returnValue,\n  };\n\n  const rscOptions = { temporaryReferences };\n  const rscStream = renderToReadableStream<RscPayload>(rscPayload, rscOptions);\n\n  // Respond RSC stream without HTML rendering as decided by `RenderRequest`\n  if (renderRequest.isRsc) {\n    return new Response(rscStream, {\n      status: actionStatus,\n      headers: {\n        \"content-type\": \"text/x-component;charset=utf-8\",\n      },\n    });\n  }\n\n  // Delegate to SSR environment for HTML rendering.\n  // The plugin provides `loadModule` helper to allow loading SSR environment entry module\n  // in RSC environment. however this can be customized by implementing own runtime communication\n  // e.g. `@cloudflare/vite-plugin`'s service binding.\n  const ssrEntryModule = await import.meta.viteRsc.loadModule<typeof import(\"./entry.ssr.tsx\")>(\n    \"ssr\",\n    \"index\"\n  );\n\n  const ssrResult = await ssrEntryModule.renderHTML(rscStream, {\n    formState,\n    // Allow quick simulation of JavaScript disabled browser\n    debugNoJS: renderRequest.url.searchParams.has(\"__nojs\"),\n  });\n\n  // Respond HTML\n  return new Response(ssrResult.stream, {\n    status: ssrResult.status,\n    headers: {\n      \"Content-Type\": \"text/html\",\n    },\n  });\n}\n\nif (import.meta.hot) {\n  import.meta.hot.accept();\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/framework/entry.ssr.tsx",
    "content": "import { createFromReadableStream } from \"@vitejs/plugin-rsc/ssr\";\nimport React from \"react\";\nimport type { ReactFormState } from \"react-dom/client\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { injectRSCPayload } from \"rsc-html-stream/server\";\nimport type { RscPayload } from \"./entry.rsc\";\n\nexport default {\n  fetch: async (request: Request) => {\n    const rscEntryModule = await import.meta.viteRsc.loadModule<typeof import(\"./entry.rsc\")>(\n      \"rsc\",\n      \"index\"\n    );\n    return rscEntryModule.default(request);\n  },\n};\n\nexport async function renderHTML(\n  rscStream: ReadableStream<Uint8Array>,\n  options: {\n    formState?: ReactFormState;\n    nonce?: string;\n    debugNoJS?: boolean;\n  }\n): Promise<{ stream: ReadableStream<Uint8Array>; status?: number }> {\n  // Duplicate one RSC stream into two.\n  // - one for SSR (ReactClient.createFromReadableStream below)\n  // - another for browser hydration payload by injecting <script>...FLIGHT_DATA...</script>.\n  const [rscStream1, rscStream2] = rscStream.tee();\n\n  // Deserialize RSC stream back to React VDOM\n  let payload: Promise<RscPayload> | undefined;\n  function SsrRoot() {\n    // Deserialization needs to be kicked off inside ReactDOMServer context\n    // for ReactDOMServer preinit/preloading to work\n    payload ??= createFromReadableStream<RscPayload>(rscStream1);\n    return React.use(payload).root;\n  }\n\n  // Render HTML (traditional SSR)\n  const bootstrapScriptContent = await import.meta.viteRsc.loadBootstrapScriptContent(\"index\");\n\n  let htmlStream: ReadableStream<Uint8Array>;\n  let status: number | undefined;\n\n  try {\n    htmlStream = await renderToReadableStream(<SsrRoot />, {\n      bootstrapScriptContent: options?.debugNoJS ? undefined : bootstrapScriptContent,\n      nonce: options?.nonce,\n      formState: options?.formState,\n    });\n  } catch {\n    // fallback to render an empty shell and run pure CSR on browser,\n    // which can replay server component error and trigger error boundary.\n    status = 500;\n    htmlStream = await renderToReadableStream(\n      <html>\n        <body>\n          <noscript>Internal Server Error: SSR failed</noscript>\n        </body>\n      </html>,\n      {\n        bootstrapScriptContent:\n          `self.__NO_HYDRATE=1;` + (options?.debugNoJS ? \"\" : bootstrapScriptContent),\n        nonce: options?.nonce,\n      }\n    );\n  }\n\n  let responseStream: ReadableStream<Uint8Array> = htmlStream;\n  if (!options?.debugNoJS) {\n    // Initial RSC stream is injected in HTML stream as <script>...FLIGHT_DATA...</script>\n    // using utility made by devongovett https://github.com/devongovett/rsc-html-stream\n    responseStream = responseStream.pipeThrough(\n      injectRSCPayload(rscStream2, {\n        nonce: options?.nonce,\n      })\n    );\n  }\n\n  return { stream: responseStream, status };\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/framework/error-boundary.tsx",
    "content": "\"use client\";\n\nimport React from \"react\";\n\n// Minimal ErrorBoundary example to handle errors globally on browser\nexport function GlobalErrorBoundary(props: { children?: React.ReactNode }) {\n  return <ErrorBoundary errorComponent={DefaultGlobalErrorPage}>{props.children}</ErrorBoundary>;\n}\n\n// https://github.com/vercel/next.js/blob/33f8428f7066bf8b2ec61f025427ceb2a54c4bdf/packages/next/src/client/components/error-boundary.tsx\n// https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary\nclass ErrorBoundary extends React.Component<{\n  children?: React.ReactNode;\n  errorComponent: React.FC<{\n    error: Error;\n    reset: () => void;\n  }>;\n}> {\n  override state: { error?: Error } = {};\n\n  static getDerivedStateFromError(error: Error) {\n    return { error };\n  }\n\n  reset = () => {\n    this.setState({ error: null });\n  };\n\n  override render() {\n    const error = this.state.error;\n    if (error) {\n      return <this.props.errorComponent error={error} reset={this.reset} />;\n    }\n    return this.props.children;\n  }\n}\n\n// https://github.com/vercel/next.js/blob/677c9b372faef680d17e9ba224743f44e1107661/packages/next/src/build/webpack/loaders/next-app-loader.ts#L73\n// https://github.com/vercel/next.js/blob/677c9b372faef680d17e9ba224743f44e1107661/packages/next/src/client/components/error-boundary.tsx#L145\nfunction DefaultGlobalErrorPage(props: { error: Error; reset: () => void }) {\n  return (\n    <html>\n      <head>\n        <title>Unexpected Error</title>\n      </head>\n      <body\n        style={{\n          height: \"100vh\",\n          display: \"flex\",\n          flexDirection: \"column\",\n          placeContent: \"center\",\n          placeItems: \"center\",\n          fontSize: \"16px\",\n          fontWeight: 400,\n          lineHeight: \"24px\",\n        }}\n      >\n        <p>Caught an unexpected error</p>\n        <pre>\n          Error:{\" \"}\n          {import.meta.env.DEV && \"message\" in props.error ? props.error.message : \"(Unknown)\"}\n        </pre>\n        <button\n          onClick={() => {\n            React.startTransition(() => {\n              props.reset();\n            });\n          }}\n        >\n          Reset\n        </button>\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/framework/request.tsx",
    "content": "// Framework conventions (arbitrary choices for this demo):\n// - Use `_.rsc` URL suffix to differentiate RSC requests from SSR requests\n// - Use `x-rsc-action` header to pass server action ID\nconst URL_POSTFIX = \"_.rsc\";\nconst HEADER_ACTION_ID = \"x-rsc-action\";\n\n// Parsed request information used to route between RSC/SSR rendering and action handling.\n// Created by parseRenderRequest() from incoming HTTP requests.\ntype RenderRequest = {\n  isRsc: boolean; // true if request should return RSC payload (via _.rsc suffix)\n  isAction: boolean; // true if this is a server action call (POST request)\n  actionId?: string; // server action ID from x-rsc-action header\n  request: Request; // normalized Request with _.rsc suffix removed from URL\n  url: URL; // normalized URL with _.rsc suffix removed\n};\n\nexport function createRscRenderRequest(\n  urlString: string,\n  action?: { id: string; body: BodyInit }\n): Request {\n  const url = new URL(urlString);\n  url.pathname += URL_POSTFIX;\n  const headers = new Headers();\n  if (action) {\n    headers.set(HEADER_ACTION_ID, action.id);\n  }\n  return new Request(url.toString(), {\n    method: action ? \"POST\" : \"GET\",\n    headers,\n    body: action?.body,\n  });\n}\n\nexport function parseRenderRequest(request: Request): RenderRequest {\n  const url = new URL(request.url);\n  const isAction = request.method === \"POST\";\n  if (url.pathname.endsWith(URL_POSTFIX)) {\n    url.pathname = url.pathname.slice(0, -URL_POSTFIX.length);\n    const actionId = request.headers.get(HEADER_ACTION_ID) || undefined;\n    if (request.method === \"POST\" && !actionId) {\n      throw new Error(\"Missing action id header for RSC action request\");\n    }\n    return {\n      isRsc: true,\n      isAction,\n      actionId,\n      request: new Request(url, request),\n      url,\n    };\n  } else {\n    return {\n      isRsc: false,\n      isAction,\n      request,\n      url,\n    };\n  }\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/index.css",
    "content": ":root {\n  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;\n  line-height: 1.5;\n  font-weight: 400;\n\n  color-scheme: light dark;\n  color: rgba(255, 255, 255, 0.87);\n  background-color: #242424;\n\n  font-synthesis: none;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\na {\n  font-weight: 500;\n  color: #646cff;\n  text-decoration: inherit;\n}\na:hover {\n  color: #535bf2;\n}\n\nbody {\n  margin: 0;\n  display: flex;\n  place-items: center;\n  min-width: 320px;\n  min-height: 100vh;\n}\n\nh1 {\n  font-size: 3.2em;\n  line-height: 1.1;\n}\n\nbutton {\n  border-radius: 8px;\n  border: 1px solid transparent;\n  padding: 0.6em 1.2em;\n  font-size: 1em;\n  font-weight: 500;\n  font-family: inherit;\n  background-color: #1a1a1a;\n  cursor: pointer;\n  transition: border-color 0.25s;\n}\nbutton:hover {\n  border-color: #646cff;\n}\nbutton:focus,\nbutton:focus-visible {\n  outline: 4px auto -webkit-focus-ring-color;\n}\n\n@media (prefers-color-scheme: light) {\n  :root {\n    color: #213547;\n    background-color: #ffffff;\n  }\n  a:hover {\n    color: #747bff;\n  }\n  button {\n    background-color: #f9f9f9;\n  }\n}\n\n#root {\n  max-width: 1280px;\n  margin: 0 auto;\n  padding: 2rem;\n  text-align: center;\n}\n\n.logo {\n  height: 6em;\n  padding: 1.5em;\n  will-change: filter;\n  transition: filter 300ms;\n}\n.logo:hover {\n  filter: drop-shadow(0 0 2em #646cffaa);\n}\n.logo.react:hover {\n  filter: drop-shadow(0 0 2em #61dafbaa);\n}\n\n@keyframes logo-spin {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  a:nth-of-type(2) .logo {\n    animation: logo-spin infinite 20s linear;\n  }\n}\n\n.card {\n  padding: 1rem;\n}\n\n.read-the-docs {\n  color: #888;\n  text-align: left;\n}\n"
  },
  {
    "path": "examples/vite-rsc/app/root.tsx",
    "content": "import \"./index.css\"; // css import is automatically injected in exported server components\nimport viteLogo from \"./assets/vite.svg\";\nimport { getServerCounter, updateServerCounter } from \"./action.tsx\";\nimport reactLogo from \"./assets/react.svg\";\nimport nitroLogo from \"./assets/nitro.svg\";\nimport { ClientCounter } from \"./client.tsx\";\n\nexport function Root(props: { url: URL }) {\n  return (\n    <html lang=\"en\">\n      <head>\n        {/* eslint-disable-next-line unicorn/text-encoding-identifier-case */}\n        <meta charSet=\"UTF-8\" />\n        <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <title>Nitro + Vite + RSC</title>\n      </head>\n      <body>\n        <App {...props} />\n      </body>\n    </html>\n  );\n}\n\nfunction App(props: { url: URL }) {\n  return (\n    <div id=\"root\">\n      <div>\n        <a href=\"https://vite.dev\" target=\"_blank\">\n          <img src={viteLogo} className=\"logo\" alt=\"Vite logo\" />\n        </a>\n        <a href=\"https://react.dev/reference/rsc/server-components\" target=\"_blank\">\n          <img src={reactLogo} className=\"logo react\" alt=\"React logo\" />\n        </a>\n\n        <a href=\"https://nitro.build\" target=\"_blank\">\n          <img src={nitroLogo} className=\"logo\" alt=\"Nitro logo\" />\n        </a>\n      </div>\n      <h1>Vite + RSC + Nitro</h1>\n      <div className=\"card\">\n        <ClientCounter />\n      </div>\n      <div className=\"card\">\n        <form action={updateServerCounter.bind(null, 1)}>\n          <button>Server Counter: {getServerCounter()}</button>\n        </form>\n      </div>\n      <div className=\"card\">Request URL: {props.url?.href}</div>\n      <ul className=\"read-the-docs\">\n        <li>\n          Edit <code>src/client.tsx</code> to test client HMR.\n        </li>\n        <li>\n          Edit <code>src/root.tsx</code> to test server HMR.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"./_.rsc\" target=\"_blank\">\n            <code>_.rsc</code>\n          </a>{\" \"}\n          to view RSC stream payload.\n        </li>\n        <li>\n          Visit{\" \"}\n          <a href=\"?__nojs\" target=\"_blank\">\n            <code>?__nojs</code>\n          </a>{\" \"}\n          to test server action without js enabled.\n        </li>\n      </ul>\n    </div>\n  );\n}\n"
  },
  {
    "path": "examples/vite-rsc/package.json",
    "content": "{\n  \"name\": \"@vitejs/plugin-rsc-examples-starter\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"@vitejs/plugin-rsc\": \"^0.5.21\",\n    \"nitro\": \"latest\",\n    \"rsc-html-stream\": \"^0.0.7\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-rsc/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n    \"types\": [\"vite/client\", \"@vitejs/plugin-rsc/types\"],\n    \"jsx\": \"react-jsx\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-rsc/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nimport rsc from \"@vitejs/plugin-rsc\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n  plugins: [\n    nitro(),\n    rsc({\n      serverHandler: false,\n      entries: {\n        ssr: \"./app/framework/entry.ssr.tsx\",\n        rsc: \"./app/framework/entry.rsc.tsx\",\n      },\n    }),\n    react(),\n  ],\n\n  environments: {\n    client: {\n      build: {\n        rollupOptions: {\n          input: { index: \"./app/framework/entry.browser.tsx\" },\n        },\n      },\n    },\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-html/README.md",
    "content": "This example renders an HTML template with server-side data and streams the response word by word. It demonstrates how to use Nitro's Vite SSR integration without a framework.\n\n## Overview\n\n1. **Add the Nitro Vite plugin** to enable SSR\n2. **Create an HTML template** with a `<!--ssr-outlet-->` comment where server content goes\n3. **Create a server entry** that fetches data and returns a stream\n4. **Add API routes** for server-side data\n\n## How It Works\n\nThe `index.html` file contains an `<!--ssr-outlet-->` comment that marks where server-rendered content will be inserted. Nitro replaces this comment with the output from your server entry.\n\nThe server entry exports an object with a `fetch` method. It calls the `/quote` API route using Nitro's internal fetch, then returns a `ReadableStream` that emits the quote text word by word with a 50ms delay between each word.\n\nThe quote route fetches a JSON file of quotes from GitHub, caches the result, and returns a random quote. The server entry calls this route to get content for the page.\n"
  },
  {
    "path": "examples/vite-ssr-html/app/entry-server.ts",
    "content": "import { fetch } from \"nitro\";\n\nexport default {\n  async fetch() {\n    const quote = (await fetch(\"/quote\").then((res) => res.json())) as {\n      text: string;\n    };\n    return tokenizedStream(quote.text, 50);\n  },\n};\n\nfunction tokenizedStream(text: string, delay: number): ReadableStream<Uint8Array> {\n  const tokens = text.split(\" \");\n  return new ReadableStream({\n    start(controller) {\n      let index = 0;\n      function push() {\n        if (index < tokens.length) {\n          const word = tokens[index++] + (index < tokens.length ? \" \" : \"\");\n          controller.enqueue(new TextEncoder().encode(word));\n          setTimeout(push, delay);\n        } else {\n          controller.close();\n        }\n      }\n      push();\n    },\n  });\n}\n"
  },
  {
    "path": "examples/vite-ssr-html/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Nitro Quotes</title>\n    <style>\n      @import \"tailwindcss\";\n    </style>\n  </head>\n  <body\n    class=\"min-h-screen flex items-center justify-center p-5 bg-gradient-to-br from-indigo-500 to-purple-600 font-sans\"\n  >\n    <div class=\"max-w-xl w-full text-center text-white\">\n      <div class=\"bg-white/10 backdrop-blur-md rounded-2xl p-10 shadow-xl border border-white/20\">\n        <div\n          id=\"quote\"\n          class=\"text-[clamp(1.2rem,4vw,1.8rem)] leading-relaxed mb-5 font-light opacity-70 transition-opacity duration-500\"\n        >\n          <!--ssr-outlet-->\n        </div>\n        <div\n          id=\"author\"\n          class=\"text-[clamp(1rem,3vw,1.2rem)] opacity-0 font-normal transition-opacity duration-500\"\n        ></div>\n        <button\n          id=\"refresh-btn\"\n          class=\"mt-5 bg-white/20 border border-white/30 text-white px-6 py-3 rounded-full cursor-pointer text-sm transition hover:bg-white/30 hover:-translate-y-0.5\"\n          onclick=\"fetchQuote()\"\n        >\n          New Quote\n        </button>\n      </div>\n      <div class=\"mt-8 text-sm opacity-60\">\n        Powered by\n        <a\n          class=\"text-white no-underline border-b border-white/30 hover:border-white transition-colors\"\n          href=\"https://vitejs.dev/\"\n          >Vite</a\n        >\n        and\n        <a\n          class=\"text-white no-underline border-b border-white/30 hover:border-white transition-colors\"\n          href=\"https://github.com/nitrojs/nitro\"\n          >Nitro v3</a\n        >.\n      </div>\n    </div>\n\n    <script>\n      const quoteElement = document.getElementById(\"quote\");\n      const authorElement = document.getElementById(\"author\");\n      const refreshBtn = document.getElementById(\"refresh-btn\");\n\n      const baseQuoteClasses =\n        \"text-[clamp(1.2rem,4vw,1.8rem)] leading-relaxed mb-5 font-light transition-opacity duration-500\";\n      const loadingQuoteClasses = baseQuoteClasses + \" opacity-70\";\n      const normalQuoteClasses = baseQuoteClasses + \" opacity-100\";\n      const errorQuoteClasses = baseQuoteClasses + \" text-red-400 opacity-100 text-sm\";\n\n      const baseAuthorClasses =\n        \"text-[clamp(1rem,3vw,1.2rem)] font-normal transition-opacity duration-500\";\n      const hiddenAuthorClasses = baseAuthorClasses + \" opacity-0\";\n      const visibleAuthorClasses = baseAuthorClasses + \" opacity-80\";\n\n      async function fetchQuote() {\n        try {\n          quoteElement.textContent = \"Loading...\";\n          quoteElement.className = loadingQuoteClasses;\n          authorElement.textContent = \"\";\n          authorElement.className = hiddenAuthorClasses;\n          refreshBtn.style.display = \"none\";\n          const response = await fetch(\"/quote\");\n          if (!response.ok) {\n            throw new Error(`HTTP error! status: ${response.status}`);\n          }\n          const { text, author } = await response.json();\n          quoteElement.textContent = `\"${text}\"`;\n          quoteElement.className = normalQuoteClasses;\n          authorElement.textContent = `— ${author}`;\n          authorElement.className = visibleAuthorClasses;\n        } catch (error) {\n          console.error(\"Error fetching quote:\", error);\n          quoteElement.textContent = \"Failed to load quote. Please try again.\";\n          quoteElement.className = errorQuoteClasses;\n          authorElement.textContent = \"\";\n          authorElement.className = hiddenAuthorClasses;\n        } finally {\n          refreshBtn.style.display = \"inline-block\";\n        }\n      }\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/vite-ssr-html/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@tailwindcss/vite\": \"^4.2.2\",\n    \"nitro\": \"latest\",\n    \"tailwindcss\": \"^4.2.2\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-html/routes/quote.ts",
    "content": "const QUOTES_URL =\n  \"https://github.com/JamesFT/Database-Quotes-JSON/raw/refs/heads/master/quotes.json\";\n\nlet _quotes: Promise<unknown> | undefined;\n\nfunction getQuotes() {\n  return (_quotes ??= fetch(QUOTES_URL).then((res) => res.json())) as Promise<\n    { quoteText: string; quoteAuthor: string }[]\n  >;\n}\n\nexport default async function quotesHandler() {\n  const quotes = await getQuotes();\n  const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];\n  return Response.json({\n    text: randomQuote.quoteText,\n    author: randomQuote.quoteAuthor,\n  });\n}\n"
  },
  {
    "path": "examples/vite-ssr-html/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/vite-ssr-html/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro({\n      serverDir: \"./\",\n    }),\n    tailwindcss(),\n  ],\n});\n"
  },
  {
    "path": "examples/vite-ssr-preact/README.md",
    "content": "Set up server-side rendering (SSR) with Preact, Vite, and Nitro. This setup enables streaming HTML responses, automatic asset management, and client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Configure client and server entry points\n3. Create a server entry that renders your app to HTML\n4. Create a client entry that hydrates the server-rendered HTML\n\n## 1. Configure Vite\n\nAdd the Nitro and Preact plugins to your Vite config. Define the `client` environment with your client entry point:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport preact from \"@preact/preset-vite\";\n\nexport default defineConfig({\n  plugins: [nitro(), preact()],\n  environments: {\n    client: {\n      build: {\n        rollupOptions: {\n          input: \"./src/entry-client.tsx\",\n        },\n      },\n    },\n  },\n});\n```\n\nThe `environments.client` configuration tells Vite which file to use as the browser entry point. Nitro automatically detects the server entry from files named `entry-server` or `server` in common directories.\n\n## 2. Create the App Component\n\nCreate a shared Preact component that runs on both server and client:\n\n```tsx [src/app.tsx]\nimport { useState } from \"preact/hooks\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>;\n}\n```\n\n## 3. Create the Server Entry\n\nThe server entry renders your Preact app to a streaming HTML response using `preact-render-to-string/stream`:\n\n```tsx [src/entry-server.tsx]\nimport \"./styles.css\";\nimport { renderToReadableStream } from \"preact-render-to-string/stream\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(request: Request) {\n    const url = new URL(request.url);\n    const htmlStream = renderToReadableStream(<Root url={url} />);\n    return new Response(htmlStream, {\n      headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n    });\n  },\n};\n\nfunction Root(props: { url: URL }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n        <script type=\"module\" src={assets.entry} />\n      </head>\n      <body>\n        <h1 className=\"hero\">Nitro + Vite + Preact</h1>\n        <p>URL: {props.url.href}</p>\n        <div id=\"app\">\n          <App />\n        </div>\n      </body>\n    </html>\n  );\n}\n```\n\nImport assets using the `?assets=client` and `?assets=ssr` query parameters. Nitro collects CSS and JS assets from each entry point, and `merge()` combines them into a single manifest. The `assets` object provides arrays of stylesheet and script attributes, plus the client entry URL. Use `renderToReadableStream` to stream HTML as Preact renders, improving time-to-first-byte.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML, attaching Preact's event handlers:\n\n```tsx [src/entry-client.tsx]\nimport { hydrate } from \"preact\";\nimport { App } from \"./app.tsx\";\n\nfunction main() {\n  hydrate(<App />, document.querySelector(\"#app\")!);\n}\n\nmain();\n```\n\nThe `hydrate` function attaches Preact to the existing server-rendered DOM inside `#app` without re-rendering it.\n"
  },
  {
    "path": "examples/vite-ssr-preact/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"@preact/preset-vite\": \"^2.10.4\",\n    \"@tailwindcss/vite\": \"^4.2.2\",\n    \"nitro\": \"latest\",\n    \"preact\": \"^10.29.0\",\n    \"preact-render-to-string\": \"^6.6.6\",\n    \"tailwindcss\": \"^4.2.2\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-preact/src/app.tsx",
    "content": "import { useState } from \"preact/hooks\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>;\n}\n"
  },
  {
    "path": "examples/vite-ssr-preact/src/entry-client.tsx",
    "content": "import { hydrate } from \"preact\";\nimport { App } from \"./app.tsx\";\n\nfunction main() {\n  hydrate(<App />, document.querySelector(\"#app\")!);\n}\n\nmain();\n"
  },
  {
    "path": "examples/vite-ssr-preact/src/entry-server.tsx",
    "content": "import \"./styles.css\";\nimport { renderToReadableStream } from \"preact-render-to-string/stream\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(request: Request) {\n    const url = new URL(request.url);\n    const htmlStream = renderToReadableStream(<Root url={url} />);\n    return new Response(htmlStream, {\n      headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n    });\n  },\n};\n\nfunction Root(props: { url: URL }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n        <script type=\"module\" src={assets.entry} />\n      </head>\n      <body>\n        <h1 className=\"hero\">Nitro + Vite + Preact</h1>\n        <p>URL: {props.url.href}</p>\n        <div id=\"app\">\n          <App />\n        </div>\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-preact/src/styles.css",
    "content": ".hero {\n  color: orange;\n}\n\nbutton {\n  background-color: lightskyblue;\n}\n"
  },
  {
    "path": "examples/vite-ssr-preact/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"preact\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-preact/vite.config.mjs",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport preact from \"@preact/preset-vite\";\n\nexport default defineConfig({\n  plugins: [nitro(), preact()],\n  environments: {\n    client: {\n      build: {\n        rollupOptions: {\n          input: \"./src/entry-client.tsx\",\n        },\n      },\n    },\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-react/README.md",
    "content": "Set up server-side rendering (SSR) with React, Vite, and Nitro. This setup enables streaming HTML responses, automatic asset management, and client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Configure client and server entry points\n3. Create a server entry that renders your app to HTML\n4. Create a client entry that hydrates the server-rendered HTML\n\n## 1. Configure Vite\n\nAdd the Nitro and React plugins to your Vite config. Define the `client` environment with your client entry point:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n  plugins: [nitro(), react()],\n  environments: {\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n```\n\nThe `environments.client` configuration tells Vite which file to use as the browser entry point. Nitro automatically detects the server entry from files named `entry-server` or `server` in common directories.\n\n## 2. Create the App Component\n\nCreate a shared React component that runs on both server and client:\n\n```tsx [src/app.tsx]\nimport { useState } from \"react\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return (\n    <>\n      <h1 className=\"hero\">Nitro + Vite + React</h1>\n      <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>\n    </>\n  );\n}\n```\n\n## 3. Create the Server Entry\n\nThe server entry renders your React app to a streaming HTML response. It uses `react-dom/server.edge` for edge-compatible streaming:\n\n```tsx [src/entry-server.tsx]\nimport \"./styles.css\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { App } from \"./app.tsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(_req: Request) {\n    const assets = clientAssets.merge(serverAssets);\n    return new Response(\n      await renderToReadableStream(\n        <html lang=\"en\">\n          <head>\n            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n            {assets.css.map((attr: any) => (\n              <link key={attr.href} rel=\"stylesheet\" {...attr} />\n            ))}\n            {assets.js.map((attr: any) => (\n              <link key={attr.href} type=\"modulepreload\" {...attr} />\n            ))}\n            <script type=\"module\" src={assets.entry} />\n          </head>\n          <body id=\"app\">\n            <App />\n          </body>\n        </html>\n      ),\n      { headers: { \"Content-Type\": \"text/html;charset=utf-8\" } }\n    );\n  },\n};\n```\n\nImport assets using the `?assets=client` and `?assets=ssr` query parameters. Nitro collects CSS and JS assets from each entry point, and `merge()` combines them into a single manifest. The `assets` object provides arrays of stylesheet and script attributes, plus the client entry URL. Use `renderToReadableStream` to stream HTML as React renders, improving time-to-first-byte.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML, attaching React's event handlers:\n\n```tsx [src/entry-client.tsx]\nimport \"@vitejs/plugin-react/preamble\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { App } from \"./app.tsx\";\n\nhydrateRoot(document.querySelector(\"#app\")!, <App />);\n```\n\nThe `@vitejs/plugin-react/preamble` import is required for React Fast Refresh during development. The `hydrateRoot` function attaches React to the existing server-rendered DOM without re-rendering it.\n"
  },
  {
    "path": "examples/vite-ssr-react/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"nitro\": \"latest\",\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\",\n    \"react-refresh\": \"^0.18.0\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-react/src/app.tsx",
    "content": "import { useState } from \"react\";\n\nexport function App() {\n  const [count, setCount] = useState(0);\n  return (\n    <>\n      <h1 className=\"hero\">Nitro + Vite + React</h1>\n      <button onClick={() => setCount((c) => c + 1)}>Count is {count}</button>\n    </>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-react/src/entry-client.tsx",
    "content": "import \"@vitejs/plugin-react/preamble\";\nimport { hydrateRoot } from \"react-dom/client\";\nimport { App } from \"./app.tsx\";\n\nhydrateRoot(document.querySelector(\"#app\")!, <App />);\n"
  },
  {
    "path": "examples/vite-ssr-react/src/entry-server.tsx",
    "content": "import \"./styles.css\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { App } from \"./app.tsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(_req: Request) {\n    const assets = clientAssets.merge(serverAssets);\n    return new Response(\n      await renderToReadableStream(\n        <html lang=\"en\">\n          <head>\n            <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n            {assets.css.map((attr: any) => (\n              <link key={attr.href} rel=\"stylesheet\" {...attr} />\n            ))}\n            {assets.js.map((attr: any) => (\n              <link key={attr.href} type=\"modulepreload\" {...attr} />\n            ))}\n            <script type=\"module\" src={assets.entry} />\n          </head>\n          <body id=\"app\">\n            <App />\n          </body>\n        </html>\n      ),\n      { headers: { \"Content-Type\": \"text/html;charset=utf-8\" } }\n    );\n  },\n};\n"
  },
  {
    "path": "examples/vite-ssr-react/src/styles.css",
    "content": ".hero {\n  color: orange;\n}\n\nbutton {\n  background-color: lightskyblue;\n}\n"
  },
  {
    "path": "examples/vite-ssr-react/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"react\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-react/vite.config.mjs",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n  plugins: [nitro(), react()],\n  environments: {\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-solid/README.md",
    "content": "Set up server-side rendering (SSR) with SolidJS, Vite, and Nitro. This setup uses `renderToStringAsync` for HTML generation and supports client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Configure client and server entry points\n3. Create a server entry that renders your app to HTML\n4. Create a client entry that hydrates the server-rendered HTML\n\n## 1. Configure Vite\n\nAdd the Nitro and SolidJS plugins to your Vite config. SolidJS requires explicit JSX configuration and both `ssr` and `client` environments:\n\n```js [vite.config.mjs]\nimport solid from \"vite-plugin-solid\";\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [solid({ ssr: true }), nitro()],\n  esbuild: { jsx: \"preserve\", jsxImportSource: \"solid-js\" },\n  environments: {\n    ssr: {\n      build: { rollupOptions: { input: \"./src/entry-server.tsx\" } },\n    },\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n```\n\nEnable SSR mode in the Solid plugin with `solid({ ssr: true })`. Configure esbuild to preserve JSX for Solid's compiler and use Solid's JSX runtime. SolidJS requires explicit `ssr` and `client` environment configuration in Vite.\n\n## 2. Create the App Component\n\nCreate a shared SolidJS component using reactive signals:\n\n```tsx [src/app.tsx]\nimport { createSignal } from \"solid-js\";\n\nexport function App() {\n  const [count, setCount] = createSignal(0);\n\n  return (\n    <div>\n      <h1>Hello, Solid!</h1>\n      <button onClick={() => setCount((count) => count + 1)}>Count: {count()}</button>\n    </div>\n  );\n}\n```\n\nSolidJS uses signals (`createSignal`) for state management. Unlike React's `useState`, signals are getter functions that you call to read the value.\n\n## 3. Create the Server Entry\n\nThe server entry renders your SolidJS app to HTML using `renderToStringAsync` and includes the `HydrationScript` for client-side hydration:\n\n```tsx [src/entry-server.tsx]\nimport { renderToStringAsync, HydrationScript } from \"solid-js/web\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(req: Request): Promise<Response> {\n    const appHTML = await renderToStringAsync(() => <App />);\n    const rootHTML = await renderToStringAsync(() => <Root appHTML={appHTML} />);\n    return new Response(rootHTML, {\n      headers: { \"Content-Type\": \"text/html\" },\n    });\n  },\n};\n\nfunction Root(props: { appHTML?: string }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n      </head>\n      <body>\n        <div id=\"app\" innerHTML={props.appHTML || \"\"} />\n        <HydrationScript />\n        <script type=\"module\" src={assets.entry} />\n      </body>\n    </html>\n  );\n}\n```\n\nSolidJS requires rendering the app separately from the shell (two-phase rendering). The app HTML is injected via `innerHTML` to preserve hydration markers. Include the `HydrationScript` component to inject the script Solid needs to rehydrate on the client. Import assets using the `?assets=client` and `?assets=ssr` query parameters to collect CSS and JS from each entry point.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML, restoring Solid's reactivity:\n\n```tsx [src/entry-client.tsx]\nimport { hydrate } from \"solid-js/web\";\nimport \"./styles.css\";\nimport { App } from \"./app.jsx\";\n\nhydrate(() => <App />, document.querySelector(\"#app\")!);\n```\n\nThe `hydrate` function attaches Solid's reactive system to the existing server-rendered DOM inside `#app`. The component is wrapped in a function `() => <App />` as required by Solid's API.\n"
  },
  {
    "path": "examples/vite-ssr-solid/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"solid-js\": \"^1.9.11\",\n    \"vite\": \"latest\",\n    \"vite-plugin-solid\": \"^2.11.11\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-solid/src/app.tsx",
    "content": "import { createSignal } from \"solid-js\";\n\nexport function App() {\n  const [count, setCount] = createSignal(0);\n\n  return (\n    <div>\n      <h1>Hello, Solid!</h1>\n      <button onClick={() => setCount((count) => count + 1)}>Count: {count()}</button>\n    </div>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-solid/src/entry-client.tsx",
    "content": "import { hydrate } from \"solid-js/web\";\nimport \"./styles.css\";\nimport { App } from \"./app.jsx\";\n\nhydrate(() => <App />, document.querySelector(\"#app\")!);\n"
  },
  {
    "path": "examples/vite-ssr-solid/src/entry-server.tsx",
    "content": "import { renderToStringAsync, HydrationScript } from \"solid-js/web\";\nimport { App } from \"./app.jsx\";\n\nimport clientAssets from \"./entry-client?assets=client\";\nimport serverAssets from \"./entry-server?assets=ssr\";\n\nexport default {\n  async fetch(req: Request): Promise<Response> {\n    const appHTML = await renderToStringAsync(() => <App />);\n    const rootHTML = await renderToStringAsync(() => <Root appHTML={appHTML} />);\n    return new Response(rootHTML, {\n      headers: { \"Content-Type\": \"text/html\" },\n    });\n  },\n};\n\nfunction Root(props: { appHTML?: string }) {\n  const assets = clientAssets.merge(serverAssets);\n  return (\n    <html lang=\"en\">\n      <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        {assets.css.map((attr: any) => (\n          <link key={attr.href} rel=\"stylesheet\" {...attr} />\n        ))}\n        {assets.js.map((attr: any) => (\n          <link key={attr.href} type=\"modulepreload\" {...attr} />\n        ))}\n      </head>\n      <body>\n        <div id=\"app\" innerHTML={props.appHTML || \"\"} />\n        <HydrationScript />\n        <script type=\"module\" src={assets.entry} />\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-solid/src/styles.css",
    "content": "div {\n  font-family: system-ui, Arial, sans-serif;\n  font-size: 20px;\n  margin-bottom: 10px;\n}\n\nbutton {\n  background-color: rgb(147 197 253);\n  color: rgb(15 23 42);\n  border: none;\n  padding: 10px 20px;\n  font-size: 16px;\n  cursor: pointer;\n  border-radius: 5px;\n}\n\nbutton:hover {\n  background-color: rgb(191 219 254);\n}\n"
  },
  {
    "path": "examples/vite-ssr-solid/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"preserve\",\n    \"jsxImportSource\": \"solid-js\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-solid/vite.config.mjs",
    "content": "import solid from \"vite-plugin-solid\";\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [solid({ ssr: true }), nitro()],\n  esbuild: { jsx: \"preserve\", jsxImportSource: \"solid-js\" },\n  environments: {\n    ssr: {\n      build: { rollupOptions: { input: \"./src/entry-server.tsx\" } },\n    },\n    client: {\n      build: { rollupOptions: { input: \"./src/entry-client.tsx\" } },\n    },\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/README.md",
    "content": "Set up TanStack Router with React, Vite, and Nitro. This setup provides file-based routing with type-safe navigation and automatic code splitting.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Create an HTML template with your app entry\n3. Create a main entry that initializes the router\n4. Define routes using file-based routing\n\n## 1. Configure Vite\n\nAdd the Nitro, React, and TanStack Router plugins to your Vite config:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\n\nexport default defineConfig({\n  plugins: [tanstackRouter({ target: \"react\", autoCodeSplitting: true }), react(), nitro()],\n});\n```\n\nThe `tanstackRouter` plugin generates a route tree from your `routes/` directory structure. Enable `autoCodeSplitting` to automatically split routes into separate chunks. Place the TanStack Router plugin before the React plugin in the array.\n\n## 2. Create the HTML Template\n\nCreate an HTML file that serves as your app shell:\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Nitro + TanStack Router + React</title>\n  </head>\n\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n```\n\n## 3. Create the App Entry\n\nCreate the main entry that initializes TanStack Router:\n\n```tsx [src/main.tsx]\nimport { StrictMode } from \"react\";\nimport ReactDOM from \"react-dom/client\";\nimport { RouterProvider, createRouter } from \"@tanstack/react-router\";\n\n// Import the generated route tree\nimport { routeTree } from \"./routeTree.gen.ts\";\n\n// Create a new router instance\nconst router = createRouter({ routeTree });\n\n// Register the router instance for type safety\ndeclare module \"@tanstack/react-router\" {\n  interface Register {\n    router: typeof router;\n  }\n}\n\n// Render the app\nconst rootElement = document.querySelector(\"#root\")!;\nif (!rootElement.innerHTML) {\n  const root = ReactDOM.createRoot(rootElement);\n  root.render(\n    <StrictMode>\n      <RouterProvider router={router} />\n    </StrictMode>\n  );\n}\n```\n\nThe `routeTree.gen.ts` file is auto-generated from your `routes/` directory structure. The `Register` interface declaration provides full type inference for route paths and params. The `!rootElement.innerHTML` check prevents re-rendering during hot module replacement.\n\n## 4. Create the Root Route\n\nThe root route (`__root.tsx`) defines your app's layout:\n\n```tsx [src/routes/__root.tsx]\nimport { createRootRoute, Link, Outlet } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\n\nconst RootLayout = () => (\n  <>\n    <div className=\"p-2 flex gap-2\">\n      <Link to=\"/\" className=\"[&.active]:font-bold\">\n        Home\n      </Link>\n    </div>\n    <hr />\n    <Outlet />\n    <TanStackRouterDevtools />\n  </>\n);\n\nexport const Route = createRootRoute({ component: RootLayout });\n```\n\nUse `Link` for type-safe navigation with active state styling. The `Outlet` component renders child routes. Include `TanStackRouterDevtools` for development tools (automatically removed in production).\n\n## 5. Create Page Routes\n\nPage routes use `createFileRoute` and can include loaders:\n\n```tsx [src/routes/index.tsx]\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({\n  loader: async () => {\n    const r = await fetch(\"/api/hello\");\n    return r.json();\n  },\n  component: Index,\n});\n\nfunction Index() {\n  const r = Route.useLoaderData();\n\n  return (\n    <div className=\"p-2\">\n      <h3>{JSON.stringify(r)}</h3>\n    </div>\n  );\n}\n```\n\nFetch data before rendering with the `loader` function—data is available via `Route.useLoaderData()`. File paths determine URL paths: `routes/index.tsx` maps to `/`, `routes/about.tsx` to `/about`, and `routes/users/$id.tsx` to `/users/:id`.\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Nitro + TanStack Router + React</title>\n  </head>\n\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@tanstack/react-router\": \"^1.168.1\",\n    \"@tanstack/react-router-devtools\": \"^1.166.10\",\n    \"@tanstack/router-plugin\": \"^1.167.1\",\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"nitro\": \"latest\",\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/src/assets/main.css",
    "content": ":root {\n  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;\n  line-height: 1.5;\n  font-weight: 400;\n\n  color-scheme: light dark;\n  color: rgba(255, 255, 255, 0.87);\n  background-color: #242424;\n\n  font-synthesis: none;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\na {\n  font-weight: 500;\n  color: #ff2056;\n  text-decoration: inherit;\n}\na:hover {\n  color: #ff637e;\n}\n\nbody {\n  margin: 0;\n  display: flex;\n  flex-direction: column;\n  place-items: center;\n  justify-content: center;\n  min-width: 320px;\n  min-height: 100vh;\n}\n\nh1 {\n  font-size: 3.2em;\n  line-height: 1.1;\n}\n\n#app {\n  max-width: 1280px;\n  margin: 0 auto;\n  padding: 2rem;\n  text-align: center;\n}\n\n.logo {\n  height: 6em;\n  padding: 1.5em;\n  will-change: filter;\n  transition: filter 300ms;\n  transition: transform 300ms;\n}\n.logo:hover {\n  transform: scale(1.1);\n}\n\n.card {\n  padding: 2em;\n}\n\n.read-the-docs {\n  color: #888;\n}\n\nbutton {\n  border-radius: 8px;\n  border: 1px solid transparent;\n  padding: 0.6em 1.2em;\n  font-size: 1em;\n  font-weight: 500;\n  font-family: inherit;\n  background-color: #1a1a1a;\n  cursor: pointer;\n  transition: border-color 0.25s;\n}\nbutton:hover {\n  border-color: #646cff;\n}\nbutton:focus,\nbutton:focus-visible {\n  outline: 4px auto -webkit-focus-ring-color;\n}\n\n@media (prefers-color-scheme: light) {\n  :root {\n    color: #213547;\n    background-color: #ffffff;\n  }\n  a:hover {\n    color: #747bff;\n  }\n  button {\n    background-color: #f9f9f9;\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/src/main.tsx",
    "content": "import { StrictMode } from \"react\";\nimport ReactDOM from \"react-dom/client\";\nimport { RouterProvider, createRouter } from \"@tanstack/react-router\";\n\n// Import the generated route tree\nimport { routeTree } from \"./routeTree.gen.ts\";\n\n// Create a new router instance\nconst router = createRouter({ routeTree });\n\n// Register the router instance for type safety\ndeclare module \"@tanstack/react-router\" {\n  interface Register {\n    router: typeof router;\n  }\n}\n\n// Render the app\nconst rootElement = document.querySelector(\"#root\")!;\nif (!rootElement.innerHTML) {\n  const root = ReactDOM.createRoot(rootElement);\n  root.render(\n    <StrictMode>\n      <RouterProvider router={router} />\n    </StrictMode>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/src/routeTree.gen.ts",
    "content": "/* eslint-disable */\n\n// @ts-nocheck\n\n// noinspection JSUnusedGlobalSymbols\n\n// This file was automatically generated by TanStack Router.\n// You should NOT make any changes in this file as it will be overwritten.\n// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.\n\nimport { Route as rootRouteImport } from './routes/__root'\nimport { Route as IndexRouteImport } from './routes/index'\n\nconst IndexRoute = IndexRouteImport.update({\n  id: '/',\n  path: '/',\n  getParentRoute: () => rootRouteImport,\n} as any)\n\nexport interface FileRoutesByFullPath {\n  '/': typeof IndexRoute\n}\nexport interface FileRoutesByTo {\n  '/': typeof IndexRoute\n}\nexport interface FileRoutesById {\n  __root__: typeof rootRouteImport\n  '/': typeof IndexRoute\n}\nexport interface FileRouteTypes {\n  fileRoutesByFullPath: FileRoutesByFullPath\n  fullPaths: '/'\n  fileRoutesByTo: FileRoutesByTo\n  to: '/'\n  id: '__root__' | '/'\n  fileRoutesById: FileRoutesById\n}\nexport interface RootRouteChildren {\n  IndexRoute: typeof IndexRoute\n}\n\ndeclare module '@tanstack/react-router' {\n  interface FileRoutesByPath {\n    '/': {\n      id: '/'\n      path: '/'\n      fullPath: '/'\n      preLoaderRoute: typeof IndexRouteImport\n      parentRoute: typeof rootRouteImport\n    }\n  }\n}\n\nconst rootRouteChildren: RootRouteChildren = {\n  IndexRoute: IndexRoute,\n}\nexport const routeTree = rootRouteImport\n  ._addFileChildren(rootRouteChildren)\n  ._addFileTypes<FileRouteTypes>()\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/src/routes/__root.tsx",
    "content": "import { createRootRoute, Link, Outlet } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\n\nconst RootLayout = () => (\n  <>\n    <div className=\"p-2 flex gap-2\">\n      <Link to=\"/\" className=\"[&.active]:font-bold\">\n        Home\n      </Link>\n    </div>\n    <hr />\n    <Outlet />\n    <TanStackRouterDevtools />\n  </>\n);\n\nexport const Route = createRootRoute({ component: RootLayout });\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/src/routes/index.tsx",
    "content": "import { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({\n  loader: async () => {\n    const r = await fetch(\"/api/hello\");\n    return r.json();\n  },\n  component: Index,\n});\n\nfunction Index() {\n  const r = Route.useLoaderData();\n\n  return (\n    <div className=\"p-2\">\n      <h3>{JSON.stringify(r)}</h3>\n    </div>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"jsx\": \"react-jsx\",\n    \"paths\": {\n      \"@/*\": [\"sec/*\"]\n    }\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tsr-react/vite.config.mjs",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport react from \"@vitejs/plugin-react\";\nimport { tanstackRouter } from \"@tanstack/router-plugin/vite\";\n\nexport default defineConfig({\n  plugins: [tanstackRouter({ target: \"react\", autoCodeSplitting: true }), react(), nitro()],\n});\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/.gitignore",
    "content": "node_modules\npackage-lock.json\nyarn.lock\n\n.DS_Store\n.cache\n.env\n.vercel\n.output\n.nitro\n/build/\n/api/\n/server/build\n/public/build# Sentry Config File\n.env.sentry-build-plugin\n/test-results/\n/playwright-report/\n/blob-report/\n/playwright/.cache/\n.tanstack"
  },
  {
    "path": "examples/vite-ssr-tss-react/README.md",
    "content": "Set up TanStack Start with Nitro for a full-stack React framework experience with server-side rendering, file-based routing, and integrated API routes.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Create a server entry using TanStack Start's server handler\n3. Configure the router with default components\n4. Define routes and API endpoints using file-based routing\n\n## 1. Configure Vite\n\nAdd the Nitro, React, TanStack Start, and Tailwind plugins to your Vite config:\n\n```js [vite.config.mjs]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport { tanstackStart } from \"@tanstack/react-start/plugin/vite\";\nimport viteReact from \"@vitejs/plugin-react\";\nimport viteTsConfigPaths from \"vite-tsconfig-paths\";\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  plugins: [\n    viteTsConfigPaths({ projects: [\"./tsconfig.json\"] }),\n    tanstackStart(),\n    viteReact(),\n    tailwindcss(),\n    nitro(),\n  ],\n  environments: {\n    ssr: { build: { rollupOptions: { input: \"./server.ts\" } } },\n  },\n});\n```\n\nThe `tanstackStart()` plugin provides full SSR integration with automatic client entry handling. Use `viteTsConfigPaths()` to enable path aliases like `~/` from tsconfig. The `environments.ssr` option points to the server entry file.\n\n## 2. Create the Server Entry\n\nCreate a server entry that uses TanStack Start's handler:\n\n```ts [server.ts]\nimport handler, { createServerEntry } from \"@tanstack/react-start/server-entry\";\n\nexport default createServerEntry({\n  fetch(request) {\n    return handler.fetch(request);\n  },\n});\n```\n\nTanStack Start handles SSR automatically. The `createServerEntry` wrapper integrates with Nitro's server entry format, and the `handler.fetch` processes all incoming requests.\n\n## 3. Configure the Router\n\nCreate a router factory function with default error and not-found components:\n\n```tsx [src/router.tsx]\nimport { createRouter } from \"@tanstack/react-router\";\nimport { routeTree } from \"./routeTree.gen.ts\";\n\nexport function getRouter() {\n  const router = createRouter({\n    routeTree,\n    defaultPreload: \"intent\",\n    defaultErrorComponent: () => <div>Internal Server Error</div>,\n    defaultNotFoundComponent: () => <div>Not Found</div>,\n    scrollRestoration: true,\n  });\n  return router;\n}\n```\n\nThe router factory configures preloading behavior, scroll restoration, and default error/not-found components.\n\n## 4. Create the Root Route\n\nThe root route defines your HTML shell with head management and scripts:\n\n```tsx [src/routes/__root.tsx]\n/// <reference types=\"vite/client\" />\nimport { HeadContent, Link, Scripts, createRootRoute } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\nimport * as React from \"react\";\nimport appCss from \"~/styles/app.css?url\";\n\nexport const Route = createRootRoute({\n  head: () => ({\n    meta: [\n      { charSet: \"utf8\" },\n      { name: \"viewport\", content: \"width=device-width, initial-scale=1\" },\n    ],\n    links: [{ rel: \"stylesheet\", href: appCss }],\n    scripts: [{ src: \"/customScript.js\", type: \"text/javascript\" }],\n  }),\n  errorComponent: () => <h1>500: Internal Server Error</h1>,\n  notFoundComponent: () => <h1>404: Page Not Found</h1>,\n  shellComponent: RootDocument,\n});\n\nfunction RootDocument({ children }: { children: React.ReactNode }) {\n  return (\n    <html>\n      <head>\n        <HeadContent />\n      </head>\n      <body>\n        <div className=\"p-2 flex gap-2 text-lg\">\n          <Link to=\"/\" activeProps={{ className: \"font-bold\" }} activeOptions={{ exact: true }}>\n            Home\n          </Link>{\" \"}\n          <Link\n            // @ts-ignore\n            to=\"/this-route-does-not-exist\"\n            activeProps={{ className: \"font-bold\" }}\n          >\n            404\n          </Link>\n        </div>\n        <hr />\n        {children}\n        <TanStackRouterDevtools position=\"bottom-right\" />\n        <Scripts />\n      </body>\n    </html>\n  );\n}\n```\n\nDefine meta tags, stylesheets, and scripts in the `head()` function. The `shellComponent` provides the HTML document shell that wraps all pages. Use `HeadContent` to render the head configuration and `Scripts` to inject the client-side JavaScript for hydration.\n\n## 5. Create Page Routes\n\nPage routes define your application pages:\n\n```tsx [src/routes/index.tsx]\nimport { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({ component: Home });\n\nfunction Home() {\n  return (\n    <div className=\"p-2\">\n      <h3>Welcome Home!</h3>\n      <a href=\"/api/test\">/api/test</a>\n    </div>\n  );\n}\n```\n\n## API Routes\n\nTanStack Start supports API routes alongside page routes. Create files in `src/routes/api/` to define server endpoints that Nitro serves automatically.\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"start\": \"node .output/server/index.mjs\"\n  },\n  \"dependencies\": {\n    \"@tanstack/react-router\": \"^1.168.1\",\n    \"@tanstack/react-router-devtools\": \"^1.166.10\",\n    \"@tanstack/react-start\": \"^1.167.1\",\n    \"nitro\": \"latest\",\n    \"react\": \"^19.2.4\",\n    \"react-dom\": \"^19.2.4\",\n    \"tailwind-merge\": \"^3.5.0\",\n    \"zod\": \"^4.3.6\"\n  },\n  \"devDependencies\": {\n    \"@tailwindcss/vite\": \"^4.2.2\",\n    \"@types/node\": \"latest\",\n    \"@types/react\": \"^19.2.14\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"@vitejs/plugin-react\": \"^5.2.0\",\n    \"tailwindcss\": \"^4.2.2\",\n    \"typescript\": \"^5.9.3\",\n    \"vite\": \"latest\",\n    \"vite-tsconfig-paths\": \"^6.1.1\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/server.ts",
    "content": "import handler, { createServerEntry } from \"@tanstack/react-start/server-entry\";\n\nexport default createServerEntry({\n  fetch(request) {\n    return handler.fetch(request);\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/src/routeTree.gen.ts",
    "content": "/* eslint-disable */\n\n// @ts-nocheck\n\n// noinspection JSUnusedGlobalSymbols\n\n// This file was automatically generated by TanStack Router.\n// You should NOT make any changes in this file as it will be overwritten.\n// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.\n\nimport { Route as rootRouteImport } from './routes/__root'\nimport { Route as IndexRouteImport } from './routes/index'\nimport { Route as ApiTestRouteImport } from './routes/api/test'\n\nconst IndexRoute = IndexRouteImport.update({\n  id: '/',\n  path: '/',\n  getParentRoute: () => rootRouteImport,\n} as any)\nconst ApiTestRoute = ApiTestRouteImport.update({\n  id: '/api/test',\n  path: '/api/test',\n  getParentRoute: () => rootRouteImport,\n} as any)\n\nexport interface FileRoutesByFullPath {\n  '/': typeof IndexRoute\n  '/api/test': typeof ApiTestRoute\n}\nexport interface FileRoutesByTo {\n  '/': typeof IndexRoute\n  '/api/test': typeof ApiTestRoute\n}\nexport interface FileRoutesById {\n  __root__: typeof rootRouteImport\n  '/': typeof IndexRoute\n  '/api/test': typeof ApiTestRoute\n}\nexport interface FileRouteTypes {\n  fileRoutesByFullPath: FileRoutesByFullPath\n  fullPaths: '/' | '/api/test'\n  fileRoutesByTo: FileRoutesByTo\n  to: '/' | '/api/test'\n  id: '__root__' | '/' | '/api/test'\n  fileRoutesById: FileRoutesById\n}\nexport interface RootRouteChildren {\n  IndexRoute: typeof IndexRoute\n  ApiTestRoute: typeof ApiTestRoute\n}\n\ndeclare module '@tanstack/react-router' {\n  interface FileRoutesByPath {\n    '/': {\n      id: '/'\n      path: '/'\n      fullPath: '/'\n      preLoaderRoute: typeof IndexRouteImport\n      parentRoute: typeof rootRouteImport\n    }\n    '/api/test': {\n      id: '/api/test'\n      path: '/api/test'\n      fullPath: '/api/test'\n      preLoaderRoute: typeof ApiTestRouteImport\n      parentRoute: typeof rootRouteImport\n    }\n  }\n}\n\nconst rootRouteChildren: RootRouteChildren = {\n  IndexRoute: IndexRoute,\n  ApiTestRoute: ApiTestRoute,\n}\nexport const routeTree = rootRouteImport\n  ._addFileChildren(rootRouteChildren)\n  ._addFileTypes<FileRouteTypes>()\n\nimport type { getRouter } from './router.tsx'\nimport type { createStart } from '@tanstack/react-start'\ndeclare module '@tanstack/react-start' {\n  interface Register {\n    ssr: true\n    router: Awaited<ReturnType<typeof getRouter>>\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/src/router.tsx",
    "content": "import { createRouter } from \"@tanstack/react-router\";\nimport { routeTree } from \"./routeTree.gen.ts\";\n\nexport function getRouter() {\n  const router = createRouter({\n    routeTree,\n    defaultPreload: \"intent\",\n    defaultErrorComponent: () => <div>Internal Server Error</div>,\n    defaultNotFoundComponent: () => <div>Not Found</div>,\n    scrollRestoration: true,\n  });\n  return router;\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/src/routes/__root.tsx",
    "content": "/// <reference types=\"vite/client\" />\nimport { HeadContent, Link, Scripts, createRootRoute } from \"@tanstack/react-router\";\nimport { TanStackRouterDevtools } from \"@tanstack/react-router-devtools\";\nimport * as React from \"react\";\nimport appCss from \"~/styles/app.css?url\";\n\nexport const Route = createRootRoute({\n  head: () => ({\n    meta: [\n      { charSet: \"utf8\" },\n      { name: \"viewport\", content: \"width=device-width, initial-scale=1\" },\n    ],\n    links: [{ rel: \"stylesheet\", href: appCss }],\n    scripts: [{ src: \"/customScript.js\", type: \"text/javascript\" }],\n  }),\n  errorComponent: () => <h1>500: Internal Server Error</h1>,\n  notFoundComponent: () => <h1>404: Page Not Found</h1>,\n  shellComponent: RootDocument,\n});\n\nfunction RootDocument({ children }: { children: React.ReactNode }) {\n  return (\n    <html>\n      <head>\n        <HeadContent />\n      </head>\n      <body>\n        <div className=\"p-2 flex gap-2 text-lg\">\n          <Link to=\"/\" activeProps={{ className: \"font-bold\" }} activeOptions={{ exact: true }}>\n            Home\n          </Link>{\" \"}\n          <Link\n            // @ts-ignore\n            to=\"/this-route-does-not-exist\"\n            activeProps={{ className: \"font-bold\" }}\n          >\n            404\n          </Link>\n        </div>\n        <hr />\n        {children}\n        <TanStackRouterDevtools position=\"bottom-right\" />\n        <Scripts />\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/src/routes/api/test.ts",
    "content": "import { createFileRoute } from \"@tanstack/react-router\";\nimport { createMiddleware, json } from \"@tanstack/react-start\";\n\nconst testMiddleware = createMiddleware().server(async ({ next }) => {\n  const result = await next();\n  result.response.headers.set(\"x-test\", \"true\");\n  return result;\n});\n\nexport const Route = createFileRoute(\"/api/test\")({\n  server: {\n    middleware: [testMiddleware],\n    handlers: {\n      GET: async ({ request }) => {\n        return json({ api: \"works!\" });\n      },\n    },\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/src/routes/index.tsx",
    "content": "import { createFileRoute } from \"@tanstack/react-router\";\n\nexport const Route = createFileRoute(\"/\")({ component: Home });\n\nfunction Home() {\n  return (\n    <div className=\"p-2\">\n      <h3>Welcome Home!</h3>\n      <a href=\"/api/test\">/api/test</a>\n    </div>\n  );\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/src/styles/app.css",
    "content": "@import \"tailwindcss\";\n\n@layer base {\n  *,\n  ::after,\n  ::before,\n  ::backdrop,\n  ::file-selector-button {\n    border-color: var(--color-gray-200, currentcolor);\n  }\n}\n\n@layer base {\n  html {\n    color-scheme: light dark;\n  }\n\n  * {\n    @apply border-gray-200 dark:border-gray-800;\n  }\n\n  html,\n  body {\n    @apply text-gray-900 bg-gray-50 dark:bg-gray-950 dark:text-gray-200;\n  }\n\n  .using-mouse * {\n    outline: none !important;\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"jsx\": \"react-jsx\",\n    \"paths\": {\n      \"~/*\": [\"./src/*\"]\n    }\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-tss-react/vite.config.mjs",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\nimport { tanstackStart } from \"@tanstack/react-start/plugin/vite\";\nimport viteReact from \"@vitejs/plugin-react\";\nimport viteTsConfigPaths from \"vite-tsconfig-paths\";\nimport tailwindcss from \"@tailwindcss/vite\";\n\nexport default defineConfig({\n  plugins: [\n    viteTsConfigPaths({ projects: [\"./tsconfig.json\"] }),\n    tanstackStart(),\n    viteReact(),\n    tailwindcss(),\n    nitro(),\n  ],\n  environments: {\n    ssr: { build: { rollupOptions: { input: \"./server.ts\" } } },\n  },\n});\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/README.md",
    "content": "Set up server-side rendering (SSR) with Vue, Vue Router, Vite, and Nitro. This setup enables per-route code splitting, head management with unhead, and client hydration.\n\n## Overview\n\n1. Add the Nitro Vite plugin to your Vite config\n2. Define routes with lazy-loaded components\n3. Create a server entry that renders your app with router support\n4. Create a client entry that hydrates and takes over routing\n5. Create page components\n\n## 1. Configure Vite\n\nAdd the Nitro and Vue plugins to your Vite config. Define both `client` and `ssr` environments:\n\n```js [vite.config.mjs]\nimport vue from \"@vitejs/plugin-vue\";\nimport { defineConfig } from \"vite\";\nimport devtoolsJson from \"vite-plugin-devtools-json\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig((_env) => ({\n  plugins: [patchVueExclude(vue(), /\\?assets/), devtoolsJson(), nitro()],\n  environments: {\n    client: { build: { rollupOptions: { input: \"./app/entry-client.ts\" } } },\n    ssr: { build: { rollupOptions: { input: \"./app/entry-server.ts\" } } },\n  },\n}));\n\n// Workaround https://github.com/vitejs/vite-plugin-vue/issues/677\nfunction patchVueExclude(plugin, exclude) {\n  const original = plugin.transform.handler;\n  plugin.transform.handler = function (...args) {\n    if (exclude.test(args[1])) return;\n    return original.call(this, ...args);\n  };\n  return plugin;\n}\n```\n\nThe `patchVueExclude` helper prevents the Vue plugin from processing asset imports (files with `?assets` query parameter).\n\n## 2. Define Routes\n\nCreate route definitions with lazy-loaded components and asset metadata:\n\n```ts [app/routes.ts]\nimport type { RouteRecordRaw } from \"vue-router\";\n\nexport const routes: RouteRecordRaw[] = [\n  {\n    path: \"/\",\n    name: \"app\",\n    component: () => import(\"./app.vue\"),\n    meta: {\n      assets: () => import(\"./app.vue?assets\"),\n    },\n    children: [\n      {\n        path: \"/\",\n        name: \"home\",\n        component: () => import(\"./pages/index.vue\"),\n        meta: {\n          assets: () => import(\"./pages/index.vue?assets\"),\n        },\n      },\n      {\n        path: \"/about\",\n        name: \"about\",\n        component: () => import(\"./pages/about.vue\"),\n        meta: {\n          assets: () => import(\"./pages/about.vue?assets\"),\n        },\n      },\n      {\n        path: \"/:catchAll(.*)\",\n        name: \"not-found\",\n        component: () => import(\"./pages/not-found.vue\"),\n        meta: {\n          assets: () => import(\"./pages/not-found.vue?assets\"),\n        },\n      },\n    ],\n  },\n];\n```\n\nUse dynamic imports for lazy-loaded components to enable code splitting. The `meta.assets` function loads route-specific CSS and JS chunks. Define child routes under a root layout component for nested routing.\n\n## 3. Create the Server Entry\n\nThe server entry renders your Vue app with router support and head management:\n\n```ts [app/entry-server.ts]\nimport { createSSRApp } from \"vue\";\nimport { renderToString } from \"vue/server-renderer\";\nimport { RouterView, createMemoryHistory, createRouter } from \"vue-router\";\nimport { createHead, transformHtmlTemplate } from \"unhead/server\";\n\nimport { routes } from \"./routes.ts\";\n\nimport clientAssets from \"./entry-client.ts?assets=client\";\n\nasync function handler(request: Request): Promise<Response> {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createMemoryHistory(), routes });\n  app.use(router);\n\n  const url = new URL(request.url);\n  const href = url.href.slice(url.origin.length);\n\n  await router.push(href);\n  await router.isReady();\n\n  const assets = clientAssets.merge(\n    ...(await Promise.all(\n      router.currentRoute.value.matched\n        .map((to) => to.meta.assets)\n        .filter(Boolean)\n        .map((fn) => (fn as any)().then((m: any) => m.default))\n    ))\n  );\n\n  const head = createHead();\n\n  head.push({\n    link: [\n      ...assets.css.map((attrs: any) => ({ rel: \"stylesheet\", ...attrs })),\n      ...assets.js.map((attrs: any) => ({ rel: \"modulepreload\", ...attrs })),\n    ],\n    script: [{ type: \"module\", src: clientAssets.entry }],\n  });\n\n  const renderedApp = await renderToString(app);\n\n  const html = await transformHtmlTemplate(head, htmlTemplate(renderedApp));\n\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n  });\n}\n\nfunction htmlTemplate(body: string): string {\n  return /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>Vue Router Custom Framework</title>\n</head>\n<body>\n  <div id=\"root\">${body}</div>\n</body>\n</html>`;\n}\n\nexport default {\n  fetch: handler,\n};\n```\n\nThe server uses `createMemoryHistory()` since there's no browser URL bar—the router navigates to the requested URL before rendering. Assets are loaded dynamically based on matched routes, ensuring only the CSS and JS needed for the current page are included. The `unhead` library manages `<head>` elements, injecting stylesheets and scripts via `transformHtmlTemplate`.\n\n## 4. Create the Client Entry\n\nThe client entry hydrates the server-rendered HTML and takes over routing:\n\n```ts [app/entry-client.ts]\nimport { createSSRApp } from \"vue\";\nimport { RouterView, createRouter, createWebHistory } from \"vue-router\";\nimport { routes } from \"./routes.ts\";\n\nasync function main() {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createWebHistory(), routes });\n  app.use(router);\n\n  await router.isReady();\n  app.mount(\"#root\");\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain();\n```\n\nThe client entry creates a Vue app with `createWebHistory()` for browser-based routing. After the router is ready, it mounts to the `#root` element and hydrates the server-rendered HTML.\n\n## 5. Create the Root Component\n\nThe root component provides navigation and renders child routes:\n\n```vue [app/app.vue]\n<script setup lang=\"ts\">\nimport { RouterLink, RouterView } from \"vue-router\";\nimport \"./styles.css\";\n</script>\n\n<template>\n  <nav>\n    <ul>\n      <li>\n        <RouterLink to=\"/\" exact-active-class=\"active\">Home</RouterLink>\n      </li>\n      <li>\n        <RouterLink to=\"/about\" active-class=\"active\">About</RouterLink>\n      </li>\n    </ul>\n  </nav>\n  <RouterView />\n</template>\n\n<style scoped>\nnav {\n  background: white;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  padding: 1rem;\n}\n\nnav ul {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  display: flex;\n  gap: 2rem;\n  max-width: 800px;\n  margin: 0 auto;\n}\n\nnav a {\n  color: #666;\n  text-decoration: none;\n}\n\nnav a:hover {\n  color: #333;\n}\n\nnav a.active {\n  color: #646cff;\n}\n</style>\n```\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/app.vue",
    "content": "<script setup lang=\"ts\">\nimport { RouterLink, RouterView } from \"vue-router\";\nimport \"./styles.css\";\n</script>\n\n<template>\n  <nav>\n    <ul>\n      <li>\n        <RouterLink to=\"/\" exact-active-class=\"active\">Home</RouterLink>\n      </li>\n      <li>\n        <RouterLink to=\"/about\" active-class=\"active\">About</RouterLink>\n      </li>\n    </ul>\n  </nav>\n  <RouterView />\n</template>\n\n<style scoped>\nnav {\n  background: white;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  padding: 1rem;\n}\n\nnav ul {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n  display: flex;\n  gap: 2rem;\n  max-width: 800px;\n  margin: 0 auto;\n}\n\nnav a {\n  color: #666;\n  text-decoration: none;\n}\n\nnav a:hover {\n  color: #333;\n}\n\nnav a.active {\n  color: #646cff;\n}\n</style>\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/entry-client.ts",
    "content": "import { createSSRApp } from \"vue\";\nimport { RouterView, createRouter, createWebHistory } from \"vue-router\";\nimport { routes } from \"./routes.ts\";\n\nasync function main() {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createWebHistory(), routes });\n  app.use(router);\n\n  await router.isReady();\n  app.mount(\"#root\");\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain();\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/entry-server.ts",
    "content": "import { createSSRApp } from \"vue\";\nimport { renderToString } from \"vue/server-renderer\";\nimport { RouterView, createMemoryHistory, createRouter } from \"vue-router\";\nimport { createHead, transformHtmlTemplate } from \"unhead/server\";\n\nimport { routes } from \"./routes.ts\";\n\nimport clientAssets from \"./entry-client.ts?assets=client\";\n\nasync function handler(request: Request): Promise<Response> {\n  const app = createSSRApp(RouterView);\n  const router = createRouter({ history: createMemoryHistory(), routes });\n  app.use(router);\n\n  const url = new URL(request.url);\n  const href = url.href.slice(url.origin.length);\n\n  await router.push(href);\n  await router.isReady();\n\n  const assets = clientAssets.merge(\n    ...(await Promise.all(\n      router.currentRoute.value.matched\n        .map((to) => to.meta.assets)\n        .filter(Boolean)\n        .map((fn) => (fn as any)().then((m: any) => m.default))\n    ))\n  );\n\n  const head = createHead();\n\n  head.push({\n    link: [\n      ...assets.css.map((attrs: any) => ({ rel: \"stylesheet\", ...attrs })),\n      ...assets.js.map((attrs: any) => ({ rel: \"modulepreload\", ...attrs })),\n    ],\n    script: [{ type: \"module\", src: clientAssets.entry }],\n  });\n\n  const renderedApp = await renderToString(app);\n\n  const html = await transformHtmlTemplate(head, htmlTemplate(renderedApp));\n\n  return new Response(html, {\n    headers: { \"Content-Type\": \"text/html;charset=utf-8\" },\n  });\n}\n\nfunction htmlTemplate(body: string): string {\n  return /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>Vue Router Custom Framework</title>\n</head>\n<body>\n  <div id=\"root\">${body}</div>\n</body>\n</html>`;\n}\n\nexport default {\n  fetch: handler,\n};\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/pages/about.vue",
    "content": "<template>\n  <main>\n    <h1>About</h1>\n    <div class=\"card\">\n      <p>This is a simple Vue Router demo app built with Vite Plugin Fullstack.</p>\n      <p>It demonstrates basic routing and server-side rendering.</p>\n    </div>\n  </main>\n</template>\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/pages/index.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref } from \"vue\";\n\nconst count = ref(0);\n\nfunction increment() {\n  count.value++;\n}\n</script>\n\n<template>\n  <main>\n    <div class=\"hero\">\n      <h1>Vue Router Custom Framework</h1>\n      <p class=\"subtitle\">A simple demo app with Vite</p>\n    </div>\n\n    <div class=\"card counter-card\">\n      <p>Count: {{ count }}</p>\n      <button @click=\"increment\">Increment</button>\n    </div>\n  </main>\n</template>\n\n<style scoped>\n.hero {\n  text-align: center;\n  margin-bottom: 2rem;\n}\n\n.hero h1 {\n  color: rgb(100, 108, 255);\n}\n\n.counter-card {\n  text-align: center;\n}\n\n.counter-card h2 {\n  color: #646cff;\n  margin-bottom: 1rem;\n}\n\n.counter-card p {\n  font-size: 1.5rem;\n  font-weight: bold;\n  margin: 1rem 0;\n}\n</style>\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/pages/not-found.vue",
    "content": "<template>\n  <main>\n    <h1>Not Found 404</h1>\n  </main>\n</template>\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/routes.ts",
    "content": "import type { RouteRecordRaw } from \"vue-router\";\n\nexport const routes: RouteRecordRaw[] = [\n  {\n    path: \"/\",\n    name: \"app\",\n    component: () => import(\"./app.vue\"),\n    meta: {\n      assets: () => import(\"./app.vue?assets\"),\n    },\n    children: [\n      {\n        path: \"/\",\n        name: \"home\",\n        component: () => import(\"./pages/index.vue\"),\n        meta: {\n          assets: () => import(\"./pages/index.vue?assets\"),\n        },\n      },\n      {\n        path: \"/about\",\n        name: \"about\",\n        component: () => import(\"./pages/about.vue\"),\n        meta: {\n          assets: () => import(\"./pages/about.vue?assets\"),\n        },\n      },\n      {\n        path: \"/:catchAll(.*)\",\n        name: \"not-found\",\n        component: () => import(\"./pages/not-found.vue\"),\n        meta: {\n          assets: () => import(\"./pages/not-found.vue?assets\"),\n        },\n      },\n    ],\n  },\n];\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/shims.d.ts",
    "content": "declare module \"*.vue\" {\n  import type { DefineComponent } from \"vue\";\n  const component: DefineComponent<{}, {}, any>;\n  export default component;\n}\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/app/styles.css",
    "content": "* {\n  box-sizing: border-box;\n}\n\nbody {\n  margin: 0;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n  background: #f5f5f5;\n  color: #333;\n}\n\nmain {\n  max-width: 800px;\n  margin: 0 auto;\n  padding: 2rem;\n}\n\nh1 {\n  font-size: 2.5rem;\n  margin-bottom: 0.5rem;\n}\n\n.card {\n  background: white;\n  border-radius: 8px;\n  padding: 2rem;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n  margin: 2rem 0;\n}\n\nbutton {\n  background: rgb(83, 91, 242);\n  color: white;\n  border: none;\n  padding: 0.5rem 1rem;\n  border-radius: 4px;\n  font-size: 1rem;\n  cursor: pointer;\n}\n\nbutton:hover {\n  background: #535bf2;\n}\n\n.subtitle {\n  color: #666;\n  font-size: 1.1rem;\n  margin-bottom: 2rem;\n}\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@vitejs/plugin-vue\": \"^6.0.5\",\n    \"nitro\": \"latest\",\n    \"unhead\": \"^2.1.12\",\n    \"vite\": \"latest\",\n    \"vite-plugin-devtools-json\": \"^1.0.0\",\n    \"vue\": \"^3.5.30\",\n    \"vue-router\": \"^4.6.4\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/vite-ssr-vue-router/vite.config.mjs",
    "content": "import vue from \"@vitejs/plugin-vue\";\nimport { defineConfig } from \"vite\";\nimport devtoolsJson from \"vite-plugin-devtools-json\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig((_env) => ({\n  plugins: [patchVueExclude(vue(), /\\?assets/), devtoolsJson(), nitro()],\n  environments: {\n    client: { build: { rollupOptions: { input: \"./app/entry-client.ts\" } } },\n    ssr: { build: { rollupOptions: { input: \"./app/entry-server.ts\" } } },\n  },\n}));\n\n// Workaround https://github.com/vitejs/vite-plugin-vue/issues/677\nfunction patchVueExclude(plugin, exclude) {\n  const original = plugin.transform.handler;\n  plugin.transform.handler = function (...args) {\n    if (exclude.test(args[1])) return;\n    return original.call(this, ...args);\n  };\n  return plugin;\n}\n"
  },
  {
    "path": "examples/vite-trpc/.gitignore",
    "content": "node_modules\ndist\n"
  },
  {
    "path": "examples/vite-trpc/README.md",
    "content": "Set up tRPC with Vite and Nitro for end-to-end typesafe APIs without code generation. This example builds a counter with server-side rendering for the initial value and client-side updates.\n\n## Overview\n\n1. Configure Vite with the Nitro plugin and route tRPC requests\n2. Create a tRPC router with procedures\n3. Create an HTML page with server-side rendering and client interactivity\n\n## 1. Configure Vite\n\nAdd the Nitro plugin and configure the `/trpc/**` route to point to your tRPC handler:\n\n```ts [vite.config.ts]\nimport { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro({\n      routes: {\n        \"/trpc/**\": \"./server/trpc.ts\",\n      },\n    }),\n  ],\n});\n```\n\nThe `routes` option maps URL patterns to handler files. All requests to `/trpc/*` are handled by the tRPC router.\n\n## 2. Create the tRPC Router\n\nDefine your tRPC router with procedures and export it as a fetch handler:\n\n```ts [server/trpc.ts]\nimport { initTRPC } from \"@trpc/server\";\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\n\nlet counter = 0;\n\nconst t = initTRPC.create();\n\nexport const appRouter = t.router({\n  get: t.procedure.query(() => {\n    return { value: counter };\n  }),\n\n  inc: t.procedure.mutation(() => {\n    counter++;\n    return { value: counter };\n  }),\n});\n\nexport type AppRouter = typeof appRouter;\n\nexport default {\n  async fetch(request: Request): Promise<Response> {\n    return fetchRequestHandler({\n      endpoint: \"/trpc\",\n      req: request,\n      router: appRouter,\n    });\n  },\n};\n```\n\nDefine procedures using `t.procedure.query()` for read operations and `t.procedure.mutation()` for write operations. Export the `AppRouter` type so clients get full type inference. The default export uses tRPC's fetch adapter to handle incoming requests.\n\n## 3. Create the HTML Page\n\nCreate an HTML page with server-side rendering and client-side interactivity:\n\n```html [index.html]\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>tRPC Counter</title>\n    <style>\n      body {\n        font-family: system-ui, sans-serif;\n        background: #0f1115;\n        color: #e5e7eb;\n        display: grid;\n        place-items: center;\n        height: 100vh;\n        margin: 0;\n      }\n\n      .box {\n        background: #181b22;\n        padding: 24px 32px;\n        border-radius: 10px;\n        text-align: center;\n        min-width: 200px;\n      }\n\n      button {\n        background: #2563eb;\n        border: none;\n        color: white;\n        padding: 8px 14px;\n        border-radius: 6px;\n        cursor: pointer;\n        margin-top: 12px;\n        font-size: 14px;\n      }\n\n      button:hover {\n        background: #1d4ed8;\n      }\n\n      .value {\n        font-size: 36px;\n        margin: 12px 0;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"box\">\n      <div>Counter</div>\n      <div class=\"value\" id=\"value\">\n        <script server>\n          // Server-side Rendering\n          const { result } = await serverFetch(\"/trpc/get\").then(r => r.json())\n          echo(result?.data?.value)\n        </script>\n      </div>\n      <button id=\"inc\">Increment</button>\n    </div>\n\n    <script setup>\n      const valueEl = document.getElementById(\"value\");\n      const incBtn = document.getElementById(\"inc\");\n\n      async function call(path, body) {\n        const res = await fetch(`/trpc/${path}`, {\n          method: body ? \"POST\" : \"GET\",\n          headers: { \"content-type\": \"application/json\" },\n          body: body ? JSON.stringify(body) : undefined,\n        });\n\n        const json = await res.json();\n        return json.result.data;\n      }\n\n      async function refresh() {\n        const data = await call(\"get\");\n        valueEl.textContent = data.value;\n      }\n\n      incBtn.onclick = async () => {\n        const data = await call(\"inc\", {});\n        valueEl.textContent = data.value;\n      };\n\n      refresh();\n    </script>\n  </body>\n</html>\n```\n\nThe `<script server>` block runs on the server before sending the response, fetching the initial counter value via `serverFetch`. The `<script setup>` block runs in the browser and handles the increment button click.\n"
  },
  {
    "path": "examples/vite-trpc/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>tRPC Counter</title>\n    <style>\n      body {\n        font-family: system-ui, sans-serif;\n        background: #0f1115;\n        color: #e5e7eb;\n        display: grid;\n        place-items: center;\n        height: 100vh;\n        margin: 0;\n      }\n\n      .box {\n        background: #181b22;\n        padding: 24px 32px;\n        border-radius: 10px;\n        text-align: center;\n        min-width: 200px;\n      }\n\n      button {\n        background: #2563eb;\n        border: none;\n        color: white;\n        padding: 8px 14px;\n        border-radius: 6px;\n        cursor: pointer;\n        margin-top: 12px;\n        font-size: 14px;\n      }\n\n      button:hover {\n        background: #1d4ed8;\n      }\n\n      .value {\n        font-size: 36px;\n        margin: 12px 0;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"box\">\n      <div>Counter</div>\n      <div class=\"value\" id=\"value\">\n        <script server>\n          // Server-side Rendering\n          const { result } = await serverFetch(\"/trpc/get\").then(r => r.json())\n          echo(result?.data?.value)\n        </script>\n      </div>\n      <button id=\"inc\">Increment</button>\n    </div>\n\n    <script setup>\n      const valueEl = document.getElementById(\"value\");\n      const incBtn = document.getElementById(\"inc\");\n\n      async function call(path, body) {\n        const res = await fetch(`/trpc/${path}`, {\n          method: body ? \"POST\" : \"GET\",\n          headers: { \"content-type\": \"application/json\" },\n          body: body ? JSON.stringify(body) : undefined,\n        });\n\n        const json = await res.json();\n        return json.result.data;\n      }\n\n      async function refresh() {\n        const data = await call(\"get\");\n        valueEl.textContent = data.value;\n      }\n\n      incBtn.onclick = async () => {\n        const data = await call(\"inc\", {});\n        valueEl.textContent = data.value;\n      };\n\n      refresh();\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/vite-trpc/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"@trpc/client\": \"^11.13.4\",\n    \"@trpc/server\": \"^11.13.4\",\n    \"nitro\": \"latest\",\n    \"vite\": \"latest\",\n    \"zod\": \"^4.3.6\"\n  }\n}\n"
  },
  {
    "path": "examples/vite-trpc/server/trpc.ts",
    "content": "import { initTRPC } from \"@trpc/server\";\nimport { fetchRequestHandler } from \"@trpc/server/adapters/fetch\";\n\nlet counter = 0;\n\nconst t = initTRPC.create();\n\nexport const appRouter = t.router({\n  get: t.procedure.query(() => {\n    return { value: counter };\n  }),\n\n  inc: t.procedure.mutation(() => {\n    counter++;\n    return { value: counter };\n  }),\n});\n\nexport type AppRouter = typeof appRouter;\n\nexport default {\n  async fetch(request: Request): Promise<Response> {\n    return fetchRequestHandler({\n      endpoint: \"/trpc\",\n      req: request,\n      router: appRouter,\n    });\n  },\n};\n"
  },
  {
    "path": "examples/vite-trpc/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {}\n}\n"
  },
  {
    "path": "examples/vite-trpc/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [\n    nitro({\n      routes: {\n        \"/trpc/**\": \"./server/trpc.ts\",\n      },\n    }),\n  ],\n});\n"
  },
  {
    "path": "examples/websocket/README.md",
    "content": "This example implements a simple chat room using WebSockets. Clients connect, send messages, and receive messages from other users in real-time. The server broadcasts messages to all connected clients using pub/sub channels.\n\n## WebSocket Handler\n\nCreate a WebSocket route using `defineWebSocketHandler`.\n\n```ts [routes/_ws.ts]\nimport { defineWebSocketHandler } from \"nitro\";\n\nexport default defineWebSocketHandler({\n  open(peer) {\n    peer.send({ user: \"server\", message: `Welcome ${peer}!` });\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} joined!` });\n    peer.subscribe(\"chat\");\n  },\n  message(peer, message) {\n    if (message.text().includes(\"ping\")) {\n      peer.send({ user: \"server\", message: \"pong\" });\n    } else {\n      const msg = {\n        user: peer.toString(),\n        message: message.toString(),\n      };\n      peer.send(msg); // echo\n      peer.publish(\"chat\", msg);\n    }\n  },\n  close(peer) {\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} left!` });\n  },\n});\n```\n\nDifferent hooks are exposed by `defineWebSocketHandler()` to integrate with different parts of the websocket lifecycle.\n"
  },
  {
    "path": "examples/websocket/index.html",
    "content": "<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <title>CrossWS Test Page</title>\n    <script src=\"https://cdn.tailwindcss.com\"></script>\n    <style>\n      body {\n        background-color: #1a1a1a;\n      }\n    </style>\n    <script type=\"module\">\n      import { createApp, reactive, nextTick } from \"https://esm.sh/petite-vue@0.4.1\";\n\n      let ws;\n\n      const store = reactive({\n        message: \"\",\n        messages: [],\n      });\n\n      const scroll = () => {\n        nextTick(() => {\n          const el = document.querySelector(\"#messages\");\n          el.scrollTop = el.scrollHeight;\n          el.scrollTo({\n            top: el.scrollHeight,\n            behavior: \"smooth\",\n          });\n        });\n      };\n\n      const format = async () => {\n        for (const message of store.messages) {\n          if (!message._fmt && message.text.startsWith(\"{\")) {\n            message._fmt = true;\n            const { codeToHtml } = await import(\"https://esm.sh/shiki@1.0.0\");\n            const str = JSON.stringify(JSON.parse(message.text), null, 2);\n            message.formattedText = await codeToHtml(str, {\n              lang: \"json\",\n              theme: \"dark-plus\",\n            });\n          }\n        }\n      };\n\n      const log = (user, ...args) => {\n        console.log(\"[ws]\", user, ...args);\n        store.messages.push({\n          text: args.join(\" \"),\n          formattedText: \"\",\n          user: user,\n          date: new Date().toLocaleString(),\n        });\n        scroll();\n        format();\n      };\n\n      const connect = async () => {\n        const isSecure = location.protocol === \"https:\";\n        const url = (isSecure ? \"wss://\" : \"ws://\") + location.host + \"/_ws\";\n        if (ws) {\n          log(\"ws\", \"Closing previous connection before reconnecting...\");\n          ws.close();\n          clear();\n        }\n\n        log(\"ws\", \"Connecting to\", url, \"...\");\n        ws = new WebSocket(url);\n\n        ws.addEventListener(\"message\", async (event) => {\n          let data = typeof event.data === \"string\" ? event.data : await event.data.text();\n          const { user = \"system\", message = \"\" } = data.startsWith(\"{\")\n            ? JSON.parse(data)\n            : { message: data };\n          log(user, typeof message === \"string\" ? message : JSON.stringify(message));\n        });\n\n        await new Promise((resolve) => ws.addEventListener(\"open\", resolve));\n        log(\"ws\", \"Connected!\");\n      };\n\n      const clear = () => {\n        store.messages.splice(0, store.messages.length);\n        log(\"system\", \"previous messages cleared\");\n      };\n\n      const send = () => {\n        console.log(\"sending message...\");\n        if (store.message) {\n          ws.send(store.message);\n        }\n        store.message = \"\";\n      };\n\n      const ping = () => {\n        log(\"ws\", \"Sending ping\");\n        ws.send(\"ping\");\n      };\n\n      createApp({\n        store,\n        send,\n        ping,\n        clear,\n        connect,\n        rand: Math.random(),\n      }).mount();\n\n      await connect();\n    </script>\n  </head>\n  <body class=\"h-screen flex flex-col justify-between\">\n    <main v-scope=\"{}\">\n      <!-- Messages -->\n      <div id=\"messages\" class=\"flex-grow flex flex-col justify-end px-4 py-8\">\n        <div class=\"flex items-center mb-4\" v-for=\"message in store.messages\">\n          <div class=\"flex flex-col\">\n            <p class=\"text-gray-500 mb-1 text-xs ml-10\">{{ message.user }}</p>\n            <div class=\"flex items-center\">\n              <img\n                :src=\"'https://www.gravatar.com/avatar/' + encodeURIComponent(message.user + rand) + '?s=512&d=monsterid'\"\n                alt=\"Avatar\"\n                class=\"w-8 h-8 rounded-full\"\n              />\n              <div class=\"ml-2 bg-gray-800 rounded-lg p-2\">\n                <p\n                  v-if=\"message.formattedText\"\n                  class=\"overflow-x-scroll\"\n                  v-html=\"message.formattedText\"\n                ></p>\n                <p v-else class=\"text-white\">{{ message.text }}</p>\n              </div>\n            </div>\n            <p class=\"text-gray-500 mt-1 text-xs ml-10\">{{ message.date }}</p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Chatbox -->\n      <div class=\"bg-gray-800 px-4 py-2 flex items-center justify-between fixed bottom-0 w-full\">\n        <div class=\"w-full min-w-6\">\n          <input\n            type=\"text\"\n            placeholder=\"Type your message...\"\n            class=\"w-full rounded-l-lg px-4 py-2 bg-gray-700 text-white focus:outline-none focus:ring focus:border-blue-300\"\n            @keydown.enter=\"send\"\n            v-model=\"store.message\"\n          />\n        </div>\n        <div class=\"flex\">\n          <button class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4\" @click=\"send\">\n            Send\n          </button>\n          <button class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4\" @click=\"ping\">\n            Ping\n          </button>\n          <button class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4\" @click=\"connect\">\n            Reconnect\n          </button>\n          <button\n            class=\"bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded-r-lg\"\n            @click=\"clear\"\n          >\n            Clear\n          </button>\n        </div>\n      </div>\n    </main>\n  </body>\n</html>\n`\n"
  },
  {
    "path": "examples/websocket/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./\",\n  renderer: { static: true },\n  features: { websocket: true },\n});\n"
  },
  {
    "path": "examples/websocket/package.json",
    "content": "{\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"nitro dev\",\n    \"build\": \"nitro build\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/websocket/routes/_ws.ts",
    "content": "import { defineWebSocketHandler } from \"nitro\";\n\nexport default defineWebSocketHandler({\n  open(peer) {\n    peer.send({ user: \"server\", message: `Welcome ${peer}!` });\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} joined!` });\n    peer.subscribe(\"chat\");\n  },\n  message(peer, message) {\n    if (message.text().includes(\"ping\")) {\n      peer.send({ user: \"server\", message: \"pong\" });\n    } else {\n      const msg = {\n        user: peer.toString(),\n        message: message.toString(),\n      };\n      peer.send(msg); // echo\n      peer.publish(\"chat\", msg);\n    }\n  },\n  close(peer) {\n    peer.publish(\"chat\", { user: \"server\", message: `${peer} left!` });\n  },\n});\n"
  },
  {
    "path": "examples/websocket/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "examples/websocket/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({ plugins: [nitro()] });\n"
  },
  {
    "path": "lib/h3.d.mts",
    "content": "export * from \"h3\";\n"
  },
  {
    "path": "lib/h3.mjs",
    "content": "export * from \"h3\";\n"
  },
  {
    "path": "lib/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"lib\": [\"ESNext\", \"DOM\"],\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Bundler\",\n    \"moduleDetection\": \"force\",\n    \"isolatedModules\": true,\n    \"verbatimModuleSyntax\": true,\n\n    \"allowJs\": true,\n    \"allowImportingTsExtensions\": true,\n    \"strict\": true,\n    \"noEmit\": true,\n    \"skipLibCheck\": true,\n    \"resolveJsonModule\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"noImplicitOverride\": true,\n    \"resolvePackageJsonImports\": true,\n\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true\n  }\n}\n"
  },
  {
    "path": "lib/vite.types.d.mts",
    "content": "// Based on https://github.com/hi-ogawa/vite-plugin-fullstack/blob/main/types/query.d.ts\n\ntype ImportAssetsResult = ImportAssetsResultRaw & {\n  merge(...args: ImportAssetsResultRaw[]): ImportAssetsResult;\n};\n\ntype ImportAssetsResultRaw = {\n  entry?: string;\n  js: { href: string }[];\n  css: { href: string; \"data-vite-dev-id\"?: string }[];\n};\n\ndeclare module \"*?assets\" {\n  const assets: ImportAssetsResult;\n  export default assets;\n}\n\ndeclare module \"*?assets=client\" {\n  const assets: ImportAssetsResult;\n  export default assets;\n}\n\ndeclare module \"*?assets=ssr\" {\n  const assets: ImportAssetsResult;\n  export default assets;\n}\n"
  },
  {
    "path": "lib/vite.types.mjs",
    "content": "// eslint-disable-next-line unicorn/require-module-specifiers\nexport {};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nitro\",\n  \"version\": \"3.0.260311-beta\",\n  \"description\": \"Build and Deploy Universal JavaScript Servers\",\n  \"keywords\": [\n    \"api-routes\",\n    \"full-stack\",\n    \"h3\",\n    \"nitro\",\n    \"server\",\n    \"typescript\",\n    \"vite\",\n    \"vite-plugin\",\n    \"web\"\n  ],\n  \"homepage\": \"https://nitro.build\",\n  \"license\": \"MIT\",\n  \"repository\": \"nitrojs/nitro\",\n  \"bin\": {\n    \"nitro\": \"./dist/cli/index.mjs\"\n  },\n  \"files\": [\n    \"dist\",\n    \"lib\",\n    \"skills\"\n  ],\n  \"type\": \"module\",\n  \"types\": \"./lib/index.d.mts\",\n  \"imports\": {\n    \"#nitro/runtime/*\": \"./dist/runtime/internal/*.mjs\",\n    \"#nitro/virtual/*\": \"./dist/runtime/virtual/*.mjs\"\n  },\n  \"exports\": {\n    \".\": \"./dist/runtime/nitro.mjs\",\n    \"./app\": \"./dist/runtime/app.mjs\",\n    \"./builder\": \"./dist/builder.mjs\",\n    \"./cache\": \"./dist/runtime/cache.mjs\",\n    \"./config\": \"./dist/runtime/config.mjs\",\n    \"./context\": \"./dist/runtime/context.mjs\",\n    \"./database\": \"./dist/runtime/database.mjs\",\n    \"./h3\": \"./lib/h3.mjs\",\n    \"./meta\": \"./dist/runtime/meta.mjs\",\n    \"./package.json\": \"./package.json\",\n    \"./runtime-config\": \"./dist/runtime/runtime-config.mjs\",\n    \"./storage\": \"./dist/runtime/storage.mjs\",\n    \"./task\": \"./dist/runtime/task.mjs\",\n    \"./tsconfig\": \"./lib/tsconfig.json\",\n    \"./types\": \"./dist/types/index.mjs\",\n    \"./vite\": \"./dist/vite.mjs\",\n    \"./vite/runtime\": \"./dist/runtime/vite.mjs\",\n    \"./vite/types\": \"./lib/vite.types.mjs\"\n  },\n  \"scripts\": {\n    \"build\": \"pnpm gen-presets && obuild\",\n    \"dev\": \"pnpm -C playground dev\",\n    \"dev:build\": \"pnpm -C playground build\",\n    \"dev:start\": \"node playground/.output/server/index.mjs\",\n    \"gen-node-compat\": \"node scripts/gen-node-compat.ts\",\n    \"gen-presets\": \"obuild --stub && node ./scripts/gen-presets.ts\",\n    \"lint\": \"oxlint . && oxfmt --check .\",\n    \"format\": \"automd && oxlint --fix . && oxfmt .\",\n    \"nitro\": \"node ./src/cli/index.ts\",\n    \"release\": \"node ./scripts/release.js\",\n    \"stub\": \"obuild --stub\",\n    \"test\": \"pnpm lint && pnpm typecheck && pnpm test:rollup && pnpm test:rolldown\",\n    \"test:rolldown\": \"NITRO_BUILDER=rolldown pnpm vitest\",\n    \"test:rollup\": \"NITRO_BUILDER=rollup pnpm vitest\",\n    \"typecheck\": \"tsgo --noEmit --skipLibCheck\"\n  },\n  \"dependencies\": {\n    \"consola\": \"^3.4.2\",\n    \"crossws\": \"^0.4.4\",\n    \"db0\": \"^0.3.4\",\n    \"env-runner\": \"^0.1.6\",\n    \"h3\": \"^2.0.1-rc.17\",\n    \"hookable\": \"^6.1.0\",\n    \"nf3\": \"^0.3.13\",\n    \"ocache\": \"^0.1.4\",\n    \"ofetch\": \"^2.0.0-alpha.3\",\n    \"ohash\": \"^2.0.11\",\n    \"rolldown\": \"^1.0.0-rc.10\",\n    \"srvx\": \"^0.11.12\",\n    \"unenv\": \"^2.0.0-rc.24\",\n    \"unstorage\": \"^2.0.0-alpha.7\"\n  },\n  \"devDependencies\": {\n    \"@azure/functions\": \"^3.5.1\",\n    \"@azure/static-web-apps-cli\": \"^2.0.8\",\n    \"@cloudflare/workers-types\": \"^4.20260317.1\",\n    \"@deno/types\": \"^0.0.1\",\n    \"@hiogawa/vite-plugin-fullstack\": \"^0.0.11\",\n    \"@netlify/edge-functions\": \"^3.0.6\",\n    \"@netlify/functions\": \"^5.1.5\",\n    \"@rollup/plugin-alias\": \"^6.0.0\",\n    \"@rollup/plugin-commonjs\": \"^29.0.2\",\n    \"@rollup/plugin-inject\": \"^5.0.5\",\n    \"@rollup/plugin-json\": \"^6.1.0\",\n    \"@rollup/plugin-node-resolve\": \"^16.0.3\",\n    \"@rollup/plugin-replace\": \"^6.0.3\",\n    \"@scalar/api-reference\": \"^1.49.3\",\n    \"@types/aws-lambda\": \"^8.10.161\",\n    \"@types/estree\": \"^1.0.8\",\n    \"@types/etag\": \"^1.8.4\",\n    \"@types/http-proxy\": \"^1.17.17\",\n    \"@types/node\": \"^25.5.0\",\n    \"@types/node-fetch\": \"^2.6.13\",\n    \"@types/semver\": \"^7.7.1\",\n    \"@types/xml2js\": \"^0.4.14\",\n    \"@typescript/native-preview\": \"latest\",\n    \"@vitest/coverage-v8\": \"^4.1.0\",\n    \"automd\": \"^0.4.3\",\n    \"c12\": \"^4.0.0-beta.4\",\n    \"changelogen\": \"^0.6.2\",\n    \"chokidar\": \"^5.0.0\",\n    \"citty\": \"^0.2.1\",\n    \"compatx\": \"^0.2.0\",\n    \"confbox\": \"^0.2.4\",\n    \"cookie-es\": \"^2.0.0\",\n    \"croner\": \"^10.0.1\",\n    \"defu\": \"^6.1.4\",\n    \"destr\": \"^2.0.5\",\n    \"dot-prop\": \"^10.1.0\",\n    \"edge-runtime\": \"^4.0.1\",\n    \"escape-string-regexp\": \"^5.0.0\",\n    \"etag\": \"^1.8.1\",\n    \"execa\": \"^9.6.1\",\n    \"expect-type\": \"^1.3.0\",\n    \"exsolve\": \"^1.0.8\",\n    \"get-port-please\": \"^3.2.0\",\n    \"giget\": \"^3.1.2\",\n    \"gzip-size\": \"^7.0.0\",\n    \"httpxy\": \"^0.3.1\",\n    \"klona\": \"^2.0.6\",\n    \"knitwork\": \"^1.3.0\",\n    \"magic-string\": \"^0.30.21\",\n    \"mdzilla\": \"^0.0.6\",\n    \"mime\": \"^4.1.0\",\n    \"miniflare\": \"^4.20260317.1\",\n    \"mlly\": \"^1.8.2\",\n    \"nypm\": \"^0.6.5\",\n    \"obuild\": \"^0.4.32\",\n    \"oxfmt\": \"^0.40.0\",\n    \"oxlint\": \"^1.56.0\",\n    \"pathe\": \"^2.0.3\",\n    \"perfect-debounce\": \"^2.1.0\",\n    \"pkg-types\": \"^2.3.0\",\n    \"pretty-bytes\": \"^7.1.0\",\n    \"react\": \"^19.2.4\",\n    \"rendu\": \"^0.0.7\",\n    \"rollup\": \"^4.59.0\",\n    \"rou3\": \"^0.8.1\",\n    \"scule\": \"^1.3.0\",\n    \"semver\": \"^7.7.4\",\n    \"serve-placeholder\": \"^2.0.2\",\n    \"source-map\": \"^0.7.6\",\n    \"std-env\": \"^4.0.0\",\n    \"tinyglobby\": \"^0.2.15\",\n    \"tsconfck\": \"^3.1.6\",\n    \"typescript\": \"^5.9.3\",\n    \"ufo\": \"^1.6.3\",\n    \"ultrahtml\": \"^1.6.0\",\n    \"uncrypto\": \"^0.1.3\",\n    \"unctx\": \"^2.5.0\",\n    \"unimport\": \"^6.0.2\",\n    \"untyped\": \"^2.0.0\",\n    \"unwasm\": \"^0.5.3\",\n    \"vite\": \"^8.0.1\",\n    \"vite7\": \"npm:vite@^7.3.1\",\n    \"vitest\": \"^4.1.0\",\n    \"wrangler\": \"^4.76.0\",\n    \"xml2js\": \"^0.6.2\",\n    \"youch\": \"^4.1.0\",\n    \"youch-core\": \"^0.3.3\",\n    \"zephyr-agent\": \"^0.1.16\"\n  },\n  \"peerDependencies\": {\n    \"dotenv\": \"*\",\n    \"giget\": \"*\",\n    \"jiti\": \"^2.6.1\",\n    \"rollup\": \"^4.59.0\",\n    \"vite\": \"^7 || ^8\",\n    \"xml2js\": \"^0.6.2\",\n    \"zephyr-agent\": \"^0.1.15\"\n  },\n  \"peerDependenciesMeta\": {\n    \"dotenv\": {\n      \"optional\": true\n    },\n    \"rollup\": {\n      \"optional\": true\n    },\n    \"vite\": {\n      \"optional\": true\n    },\n    \"xml2js\": {\n      \"optional\": true\n    },\n    \"giget\": {\n      \"optional\": true\n    },\n    \"jiti\": {\n      \"optional\": true\n    },\n    \"zephyr-agent\": {\n      \"optional\": true\n    }\n  },\n  \"resolutions\": {\n    \"nitro\": \"link:.\"\n  },\n  \"engines\": {\n    \"node\": \"^20.19.0 || >=22.12.0\"\n  },\n  \"packageManager\": \"pnpm@10.32.0\",\n  \"compatiblePackages\": {\n    \"schemaVersion\": 1,\n    \"vite\": {\n      \"type\": \"compatible\",\n      \"versions\": \"^7 || ^8\"\n    },\n    \"rollup\": {\n      \"type\": \"compatible\",\n      \"versions\": \"^4\"\n    },\n    \"rolldown\": {\n      \"type\": \"compatible\",\n      \"versions\": \">=1.0.0-beta.0\"\n    }\n  }\n}\n"
  },
  {
    "path": "playground/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nexport default defineConfig({\n  serverDir: \"./server\",\n});\n"
  },
  {
    "path": "playground/package.json",
    "content": "{\n  \"name\": \"nitro-playground\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"vite build\",\n    \"dev\": \"vite dev\",\n    \"preview\": \"vite preview\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"link:..\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "playground/server.ts",
    "content": "export default {\n  fetch(req: Request) {\n    return new Response(\"Hello from Nitro playground!\");\n  },\n};\n"
  },
  {
    "path": "playground/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "playground/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - examples/**\n  - playground\n  - test/fixture\n  - test/minimal\n\nignoreWorkspaceRootCheck: true\n\nignoredBuiltDependencies:\n  - keytar\n  - protobufjs\n  - vue-demi\n\nonlyBuiltDependencies:\n  - '@parcel/watcher'\n  - esbuild\n  - ocache\n  - sharp\n  - workerd\n\npeerDependencyRules:\n  ignoreMissing:\n    - react\n    - '@types/react'\n    - react-dom\n    - '@algolia/client-search'\n\nshellEmulator: true\n\n# typescript-eslint is affected by\n# https://github.com/pnpm/pnpm/issues/10329\n# trustPolicy: no-downgrade\n\ntrustPolicyExclude:\n  - chokidar@4.0.3\n  - tailwind-merge@2.6.0\n  - '@headlessui/vue@1.7.23'\n  - undici-types@6.21.0\n  - rxjs@7.8.2\n  - semver@6.3.1\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\"github>unjs/renovate-config\"],\n  \"baseBranchPatterns\": [\"main\"]\n}\n"
  },
  {
    "path": "scripts/bump-nightly.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { execaCommand } from \"execa\";\nimport { glob } from \"tinyglobby\";\nimport { resolve } from \"pathe\";\n\nconst nightlyPackages = {\n  // h3: \"h3-nightly\",\n} as Record<string, string>;\n\nasync function loadPackage(dir: string) {\n  const pkgPath = resolve(dir, \"package.json\");\n  const data = JSON.parse(await fsp.readFile(pkgPath, \"utf8\").catch(() => \"{}\"));\n  const save = () => fsp.writeFile(pkgPath, JSON.stringify(data, null, 2) + \"\\n\");\n\n  const updateDeps = (reviver: (dep: any) => any) => {\n    for (const type of [\n      \"dependencies\",\n      \"devDependencies\",\n      \"optionalDependencies\",\n      \"peerDependencies\",\n    ]) {\n      if (!data[type]) {\n        continue;\n      }\n      for (const e of Object.entries(data[type])) {\n        const dep = { name: e[0], range: e[1], type };\n        delete data[type][dep.name];\n        const updated = reviver(dep) || dep;\n        data[updated.type] = data[updated.type] || {};\n        data[updated.type][updated.name] = updated.range;\n      }\n    }\n  };\n\n  return {\n    dir,\n    data,\n    save,\n    updateDeps,\n  };\n}\n\ntype ThenArg<T> = T extends PromiseLike<infer U> ? U : T;\ntype Package = ThenArg<ReturnType<typeof loadPackage>>;\n\nasync function loadWorkspace(dir: string) {\n  const workspacePkg = await loadPackage(dir);\n  const pkgDirs = await glob(workspacePkg.data.workspaces || [], {\n    onlyDirectories: true,\n  });\n\n  const packages: Package[] = [workspacePkg];\n\n  for (const pkgDir of pkgDirs) {\n    const pkg = await loadPackage(pkgDir);\n    if (!pkg.data.name) {\n      continue;\n    }\n    packages.push(pkg);\n  }\n\n  const find = (name: string) => {\n    const pkg = packages.find((pkg) => pkg.data.name === name);\n    if (!pkg) {\n      throw new Error(\"Workspace package not found: \" + name);\n    }\n    return pkg;\n  };\n\n  const rename = (from: string, to: string) => {\n    find(from).data.name = to;\n    for (const pkg of packages) {\n      pkg.updateDeps((dep) => {\n        if (dep.name === from && !dep.range.startsWith(\"npm:\")) {\n          dep.range = \"npm:\" + to + \"@\" + dep.range;\n        }\n      });\n    }\n  };\n\n  const setVersion = (name: string, newVersion: string) => {\n    find(name).data.version = newVersion;\n    for (const pkg of packages) {\n      pkg.updateDeps((dep) => {\n        if (dep.name === name) {\n          dep.range = newVersion;\n        }\n      });\n    }\n  };\n\n  const save = () => Promise.all(packages.map((pkg) => pkg.save()));\n\n  return {\n    dir,\n    workspacePkg,\n    packages,\n    save,\n    find,\n    rename,\n    setVersion,\n  };\n}\n\nfunction fmtDate(d: Date): string {\n  // YYMMDD-HHMMSS: 20240919-140954\n  const date = joinNumbers([d.getFullYear(), d.getMonth() + 1, d.getDate()]);\n  const time = joinNumbers([d.getHours(), d.getMinutes(), d.getSeconds()]);\n  return `${date}-${time}`;\n}\n\nfunction joinNumbers(items: number[]): string {\n  return items.map((i) => (i + \"\").padStart(2, \"0\")).join(\"\");\n}\n\nasync function main() {\n  const workspace = await loadWorkspace(process.cwd());\n\n  const commit = await execaCommand(\"git rev-parse --short HEAD\").then((r) => r.stdout.trim());\n\n  for (const pkg of workspace.packages.filter((p) => !p.data.private)) {\n    workspace.setVersion(pkg.data.name, `${pkg.data.version}-${fmtDate(new Date())}.${commit}`);\n    workspace.rename(pkg.data.name, pkg.data.name + \"-nightly\");\n    pkg.updateDeps((dep) => {\n      if (nightlyPackages[dep.name]) {\n        dep.range = \"npm:\" + nightlyPackages[dep.name] + \"@latest\";\n      }\n    });\n  }\n\n  await workspace.save();\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain().catch((error) => {\n  console.error(error);\n  // eslint-disable-next-line unicorn/no-process-exit\n  process.exit(1);\n});\n"
  },
  {
    "path": "scripts/bump-version.ts",
    "content": "#!/bin/env node\nimport { promises as fsp } from \"node:fs\";\nimport { resolve } from \"pathe\";\n\nconst c = {\n  cyan: (s: string) => `\\x1B[36m${s}\\x1B[0m`,\n  green: (s: string) => `\\x1B[32m${s}\\x1B[0m`,\n  yellow: (s: string) => `\\x1B[33m${s}\\x1B[0m`,\n  gray: (s: string) => `\\x1B[90m${s}\\x1B[0m`,\n  red: (s: string) => `\\x1B[31m${s}\\x1B[0m`,\n  bold: (s: string) => `\\x1B[1m${s}\\x1B[0m`,\n};\n\nexport function fmtDate(d: Date): string {\n  const y = d.getFullYear() % 100;\n  const m = (d.getMonth() + 1).toString().padStart(2, \"0\");\n  const day = d.getDate().toString().padStart(2, \"0\");\n  return `${y}${m}${day}`;\n}\n\nasync function fetchExistingVersions(pkgName: string): Promise<string[]> {\n  const url = `https://registry.npmjs.org/${pkgName}`;\n  console.log(c.gray(`Fetching versions from npm registry for ${c.cyan(pkgName)}...`));\n  try {\n    const res = await fetch(url);\n    if (!res.ok) {\n      console.log(c.yellow(`  Registry returned ${res.status}, assuming first release`));\n      return [];\n    }\n    const data = (await res.json()) as { versions?: Record<string, unknown> };\n    const versions = Object.keys(data.versions || {});\n    return versions;\n  } catch (err) {\n    console.log(c.yellow(`  Failed to fetch registry: ${err}`));\n    return [];\n  }\n}\n\nexport async function resolveVersion(\n  pkgName: string,\n  dateStr: string,\n  prerelease = \"beta\"\n): Promise<string> {\n  const versions = await fetchExistingVersions(pkgName);\n  const base = `3.0.${dateStr}`;\n  const prefix = prerelease ? `${base}-${prerelease}` : base;\n  const matching = versions.filter((v) => v.startsWith(prefix));\n\n  const sep = prerelease ? \".\" : \"-\";\n  let max = 0;\n  for (const v of matching) {\n    const rest = v.slice(prefix.length);\n    if (rest === \"\") {\n      max = Math.max(max, 1);\n    } else if (rest.startsWith(sep)) {\n      const n = Number.parseInt(rest.slice(1), 10);\n      if (!Number.isNaN(n)) {\n        max = Math.max(max, n);\n      }\n    }\n  }\n\n  const version = max === 0 ? prefix : `${prefix}${sep}${max + 1}`;\n  console.log(c.gray(`  Resolved version: ${c.cyan(version)}`));\n  return version;\n}\n\nasync function main() {\n  console.log(c.bold(\"\\nBump version to beta\\n\"));\n\n  const pkgPath = resolve(process.cwd(), \"package.json\");\n  const pkg = JSON.parse(await fsp.readFile(pkgPath, \"utf8\"));\n  const oldVersion = pkg.version;\n\n  const dateStr = fmtDate(new Date());\n  console.log(c.gray(`Date: ${c.cyan(dateStr)}`));\n\n  const newVersion = await resolveVersion(pkg.name, dateStr);\n\n  console.log();\n  console.log(`  ${c.cyan(pkg.name)} ${c.gray(oldVersion)} → ${c.green(newVersion)}`);\n\n  pkg.version = newVersion;\n  await fsp.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n\n  console.log(c.green(`\\nDone!\\n`));\n}\n\nif (process.argv[1] && import.meta.url.endsWith(process.argv[1])) {\n  main().catch((error) => {\n    console.error(c.red(`\\nError: ${error.message}\\n`));\n    process.exit(1);\n  });\n}\n"
  },
  {
    "path": "scripts/gen-node-compat.ts",
    "content": "import { writeFile } from \"node:fs/promises\";\n\nconst platforms = {\n  cloudflare: \"https://platform-node-compat.pi0.workers.dev/?ts\",\n  deno: \"https://platform-node-compat.deno.dev/?ts\",\n};\n\nfor (const platform in platforms) {\n  const url = platforms[platform as keyof typeof platforms];\n  const code = await fetch(url).then((res) => res.text());\n\n  console.log(`Fetching Node.js compatibility data for ${platform} from ${url}`);\n\n  await writeFile(\n    new URL(`../src/presets/${platform}/unenv/node-compat.ts`, import.meta.url),\n    code\n  );\n}\n"
  },
  {
    "path": "scripts/gen-presets.ts",
    "content": "import { existsSync, readFileSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { consola } from \"consola\";\nimport { findTypeExports } from \"mlly\";\nimport type { NitroPreset, NitroPresetMeta } from \"nitro/types\";\nimport { camelCase, kebabCase, pascalCase, snakeCase } from \"scule\";\n\nconst autoGenHeader = /* ts */ `// Auto-generated using gen-presets script\\n`;\n\n// --- Scan presets/ directory ---\nconst presetsDir = fileURLToPath(new URL(\"../src/presets\", import.meta.url));\nconst presetDirs: string[] = readdirSync(presetsDir, { withFileTypes: true })\n  .filter(\n    (dir) =>\n      dir.name !== \"_utils\" &&\n      dir.isDirectory() &&\n      existsSync(resolve(presetsDir, dir.name, \"preset.ts\"))\n  )\n  .map((dir) => dir.name);\n\n// --- Load presets ---\nconst allPresets: (NitroPreset & { _meta?: NitroPresetMeta })[] = [];\nfor (const preset of presetDirs) {\n  const presetPath = resolve(presetsDir, preset, \"preset.ts\");\n  const _presets = await import(pathToFileURL(presetPath).href).then(\n    (mod) => (mod as any).default || mod\n  );\n  if (!Array.isArray(_presets)) {\n    throw new TypeError(`Preset ${preset} does not export an array`);\n  }\n  allPresets.push(..._presets);\n}\n\n// --- Validate names ---\nconst _names = new Set<string>();\nfor (const preset of allPresets) {\n  if (!preset._meta?.name) {\n    consola.warn(`Preset ${preset} does not have a name`);\n    continue;\n  }\n  const names = [preset._meta.name, ...(preset._meta.aliases || [])];\n  for (const name of names) {\n    if (_names.has(name)) {\n      if (!preset._meta.compatibilityDate && !preset._meta.dev) {\n        consola.warn(`Preset ${name} is duplicated`);\n      }\n      continue;\n    }\n    if (kebabCase(name) !== name) {\n      consola.warn(`Preset ${name} is not kebab-case`);\n    }\n    _names.add(name);\n  }\n}\nconst names = [..._names].sort();\nconsola.log(names.join(\", \"));\n\n// --- Generate presets/_all.gen.ts ---\nwriteFileSync(\n  resolve(presetsDir, \"_all.gen.ts\"),\n  /* ts */ `${autoGenHeader}\n${presetDirs\n  .map((preset) => `import _${camelCase(preset)} from \"./${preset}/preset.ts\";`)\n  .join(\"\\n\")}\n\nexport default [\n${presetDirs.map((preset) => `  ..._${camelCase(preset)},`).join(\"\\n\")}\n] as const;\n`\n);\n// --- Generate presets/_types.gen.ts ---\nconst presetsWithType = presetDirs.filter((presetDir) => {\n  const presetPath = resolve(presetsDir, presetDir, \"preset.ts\");\n  const content = readFileSync(presetPath, \"utf8\");\n  const typeExports = findTypeExports(content);\n  return typeExports.some((type) => type.name === \"PresetOptions\");\n});\nwriteFileSync(\n  resolve(presetsDir, \"_types.gen.ts\"),\n  /* ts */ `${autoGenHeader}\n${presetsWithType\n  .map(\n    (preset) =>\n      `import type { PresetOptions as ${pascalCase(preset)}Options } from \"./${preset}/preset.ts\";`\n  )\n  .join(\"\\n\")}\n\nexport interface PresetOptions {\n${presetsWithType\n  .map((preset) => `  ${camelCase(preset)}?: ${pascalCase(preset)}Options;`)\n  .join(\"\\n\")}\n}\n\nexport const presetsWithConfig = ${JSON.stringify(presetsWithType.map((p) => camelCase(p)))} as const;\n\nexport type PresetName = ${names.map((name) => `\"${name}\"`).join(\" | \")};\n\nexport type PresetNameInput = ${names\n    .flatMap((name) =>\n      [...new Set([kebabCase(name), camelCase(name), snakeCase(name)])].map((n) => `\"${n}\"`)\n    )\n    .join(\" | \")} | (string & {});\n`\n);\n"
  },
  {
    "path": "scripts/release.ts",
    "content": "#!/bin/env node\nimport { execSync } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { parseArgs } from \"node:util\";\n// import { setTimeout as sleep } from \"node:timers/promises\";\n\nconst { values: args } = parseArgs({\n  allowNegative: true,\n  options: {\n    precheck: { type: \"boolean\", default: true },\n  },\n});\n\nconst c = {\n  cyan: (s: string) => `\\x1B[36m${s}\\x1B[0m`,\n  green: (s: string) => `\\x1B[32m${s}\\x1B[0m`,\n  red: (s: string) => `\\x1B[31m${s}\\x1B[0m`,\n  bold: (s: string) => `\\x1B[1m${s}\\x1B[0m`,\n  gray: (s: string) => `\\x1B[90m${s}\\x1B[0m`,\n};\n\nmain().catch((error) => {\n  console.error(c.red(`\\nError: ${error.message}\\n`));\n  process.exit(1);\n});\n\nasync function main() {\n  console.log(c.bold(\"\\n🚀 Nitro Release\\n\"));\n\n  // 1. Prechecks\n  if (!args.precheck) {\n    console.log(c.gray(\"→ Skipping prechecks (--no-precheck)\\n\"));\n  } else {\n    await precheck();\n  }\n\n  // 2. Bump version\n  console.log(c.cyan(\"\\n→ Bumping version...\\n\"));\n  run(\"node scripts/bump-version.ts\");\n\n  // 3. Read new version\n  const pkg = JSON.parse(await readFile(\"package.json\", \"utf8\"));\n  const version = `v${pkg.version}`;\n  console.log(c.cyan(`\\n→ Version: ${c.bold(version)}\\n`));\n\n  // 4. Generate release notes\n  console.log(c.cyan(\"→ Generating release notes...\\n\"));\n  run(\"pnpx changelogen --output CHANGELOG.md\");\n  console.log(c.green(\"  Written to CHANGELOG.md\"));\n\n  // 5. Commit and tag\n  console.log(c.cyan(\"\\n→ Creating release commit and tag...\\n\"));\n  run(\"git add package.json\");\n  run(`git commit -m \"${version}\"`);\n  run(`git tag -a ${version} -m \"${version}\"`);\n\n  console.log(c.green(c.bold(`\\n✅ Release ${version} prepared!\\n`)));\n\n  // Prompt to push\n  process.stdout.write(c.cyan(`  Push with ${c.bold(\"git push --follow-tags\")}? (yes/no) `));\n  const answer = await new Promise<string>((resolve) => {\n    process.stdin.setEncoding(\"utf8\");\n    process.stdin.once(\"data\", (data) => resolve(data.toString().trim()));\n  });\n  process.stdin.destroy();\n  if (answer === \"yes\") {\n    run(\"git push --follow-tags\");\n    console.log(c.green(c.bold(\"\\n🎉 Released!\\n\")));\n  } else {\n    console.log(c.cyan(`\\n  Run ${c.bold(\"git push --follow-tags\")} manually to publish.\\n`));\n  }\n}\n\nfunction run(cmd: string, opts?: { silent?: boolean; quiet?: boolean }) {\n  if (!opts?.quiet) {\n    console.log(c.gray(`$ ${cmd}`));\n  }\n  return execSync(cmd, {\n    stdio: opts?.silent ? \"pipe\" : \"inherit\",\n    encoding: \"utf8\",\n  });\n}\n\nasync function precheck() {\n  console.log(c.cyan(\"→ Running prechecks...\\n\"));\n\n  // Check we are on main branch\n  const branch = run(\"git rev-parse --abbrev-ref HEAD\", { silent: true }).trim();\n  if (branch !== \"main\") {\n    throw new Error(`Must be on \"main\" branch (currently on \"${branch}\")`);\n  }\n\n  // Check no dirty state\n  const status = run(\"git status --porcelain\", { silent: true }).trim();\n  if (status) {\n    throw new Error(`Working tree is dirty:\\n${status}`);\n  }\n\n  // Check local HEAD matches remote main\n  run(\"git fetch origin main\", { silent: true });\n  const localHead = run(\"git rev-parse HEAD\", { silent: true }).trim();\n  const remoteHead = run(\"git rev-parse origin/main\", { silent: true }).trim();\n  if (localHead !== remoteHead) {\n    throw new Error(\n      `Local HEAD (${localHead.slice(0, 8)}) does not match origin/main (${remoteHead.slice(0, 8)})`\n    );\n  }\n\n  // Check all GitHub Actions completed successfully for HEAD commit\n  // type CIRun = { status: string; conclusion: string; name: string; databaseId: number };\n  // type CIJob = { status: string; conclusion: string; name: string };\n  // const pollInterval = 15_000;\n  // let ciRuns: CIRun[] = [];\n  // // eslint-disable-next-line no-constant-condition\n  // while (true) {\n  //   ciRuns = JSON.parse(\n  //     run(\n  //       `gh run list --branch main --commit ${remoteHead} --json status,conclusion,name,databaseId`,\n  //       { silent: true, quiet: true }\n  //     )\n  //   ) as CIRun[];\n  //   if (ciRuns.length === 0) {\n  //     throw new Error(\"No GitHub Actions runs found for HEAD\");\n  //   }\n  //   const pending = ciRuns.filter((r) => r.status !== \"completed\");\n  //   if (pending.length === 0) break;\n  //   console.log(c.gray(`  Waiting for ${pending.map((r) => r.name).join(\", \")}...`));\n  //   await sleep(pollInterval);\n  // }\n\n  // // Fetch jobs for each run and print summary\n  // const allFailed: string[] = [];\n  // for (const r of ciRuns) {\n  //   const jobs = JSON.parse(\n  //     run(`gh run view ${r.databaseId} --json jobs -q \".jobs\"`, { silent: true, quiet: true })\n  //   ) as CIJob[];\n  //   const runIcon = r.conclusion === \"success\" ? c.green(\"✓\") : c.red(\"✗\");\n  //   console.log(`  ${runIcon} ${c.bold(r.name)}`);\n  //   for (const job of jobs) {\n  //     const jobIcon = job.conclusion === \"success\" ? c.green(\"✓\") : c.red(\"✗\");\n  //     console.log(`    ${jobIcon} ${job.name}`);\n  //     if (job.conclusion !== \"success\") {\n  //       allFailed.push(`${r.name} > ${job.name} (${job.conclusion})`);\n  //     }\n  //   }\n  // }\n  // if (allFailed.length > 0) {\n  //   throw new Error(`GitHub Actions failed:\\n  ${allFailed.join(\"\\n  \")}`);\n  // }\n\n  console.log(c.green(\"  All prechecks passed!\\n\"));\n}\n"
  },
  {
    "path": "scripts/vite7.ts",
    "content": "import { execSync } from \"node:child_process\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nconst pkgPath = resolve(import.meta.dirname, \"../package.json\");\nconst pkg = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n\npkg.resolutions = pkg.resolutions || {};\npkg.resolutions.vite = \"^7\";\n\nwriteFileSync(pkgPath, JSON.stringify(pkg, null, 2) + \"\\n\");\n\nconsole.log(\"Added vite: ^7 to resolutions\");\n\nexecSync(\"pnpm install --no-frozen-lockfile\", {\n  stdio: \"inherit\",\n  cwd: resolve(import.meta.dirname, \"..\"),\n});\n"
  },
  {
    "path": "skills/nitro/SKILL.md",
    "content": "---\nname: nitro\ndescription: Build and deploy universal JavaScript servers with Nitro\n---\n\n@docs/TOC.md\n\nYou can use `npx nitro docs [--page <path>] [...args]` to explore the documentation locally.\nFor example, `npx nitro docs --page /docs/routing` will open the routing page of the guide section.\nIf not available, fallback to https://nitro.build/llms.txt\n"
  },
  {
    "path": "src/build/assets.ts",
    "content": "import { existsSync, promises as fsp } from \"node:fs\";\nimport { glob } from \"tinyglobby\";\nimport { isDirectory, prettyPath } from \"../utils/fs.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { join, relative, resolve } from \"pathe\";\nimport { compressPublicAssets } from \"../utils/compress.ts\";\n\nconst NEGATION_RE = /^(!?)(.*)$/;\nconst PARENT_DIR_GLOB_RE = /!?\\.\\.\\//;\n\nexport async function scanUnprefixedPublicAssets(nitro: Nitro) {\n  const scannedPaths: string[] = [];\n  for (const asset of nitro.options.publicAssets) {\n    if (asset.baseURL && asset.baseURL !== \"/\" && !asset.fallthrough) {\n      // we can statically detect these without scanning\n      continue;\n    }\n    if (!(await isDirectory(asset.dir))) {\n      continue;\n    }\n    const includePatterns = getIncludePatterns(nitro, asset.dir, asset.ignore);\n    const publicAssets = await glob(includePatterns, {\n      cwd: asset.dir,\n      absolute: false,\n      dot: true,\n    });\n    scannedPaths.push(...publicAssets.map((file) => join(asset.baseURL || \"/\", file)));\n  }\n  return scannedPaths;\n}\n\nexport async function copyPublicAssets(nitro: Nitro) {\n  if (nitro.options.noPublicDir) {\n    return;\n  }\n  for (const asset of nitro.options.publicAssets) {\n    const assetDir = asset.dir;\n    const dstDir = join(nitro.options.output.publicDir, asset.baseURL!);\n    if (await isDirectory(assetDir)) {\n      const includePatterns = getIncludePatterns(nitro, assetDir, asset.ignore);\n      const publicAssets = await glob(includePatterns, {\n        cwd: assetDir,\n        absolute: false,\n        dot: true,\n      });\n      await Promise.all(\n        publicAssets.map(async (file) => {\n          const src = join(assetDir, file);\n          const dst = join(dstDir, file);\n          if (!existsSync(dst)) {\n            await fsp.cp(src, dst);\n          }\n        })\n      );\n    }\n  }\n  if (nitro.options.compressPublicAssets) {\n    await compressPublicAssets(nitro);\n  }\n  nitro.logger.success(\"Generated public \" + prettyPath(nitro.options.output.publicDir));\n}\n\nfunction getIncludePatterns(\n  nitro: Nitro,\n  assetDir: string,\n  ignorePatterns: string[] | false = nitro.options.ignore\n) {\n  return [\n    \"**\",\n    ...(ignorePatterns || []).map((p) => {\n      const [_, negation, pattern] = p.match(NEGATION_RE) || [];\n      return (\n        // Convert ignore to include patterns\n        (negation ? \"\" : \"!\") +\n        // Make non-glob patterns relative to publicAssetDir\n        (pattern.startsWith(\"*\")\n          ? pattern\n          : relative(assetDir, resolve(nitro.options.rootDir, pattern)))\n      );\n    }),\n  ].filter((p) => !PARENT_DIR_GLOB_RE.test(p));\n}\n"
  },
  {
    "path": "src/build/build.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nexport async function build(nitro: Nitro) {\n  switch (nitro.options.builder) {\n    case \"rollup\": {\n      const { rollupBuild } = await import(\"./rollup/build.ts\");\n      return rollupBuild(nitro);\n    }\n    case \"rolldown\": {\n      const { rolldownBuild } = await import(\"./rolldown/build.ts\");\n      return rolldownBuild(nitro);\n    }\n    case \"vite\": {\n      const { viteBuild } = await import(\"./vite/build.ts\");\n      return viteBuild(nitro);\n    }\n    default: {\n      throw new Error(`Unknown builder: ${nitro.options.builder}`);\n    }\n  }\n}\n"
  },
  {
    "path": "src/build/chunks.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\n// Tests in @test/unit/chunks.test.ts\n\nconst virtualRe = /^(?:\\0|#|virtual:)/;\n\nexport const NODE_MODULES_RE = /node_modules[/\\\\](?!(?:nitro|nitro-nightly)[/\\\\])[^.]/;\n\nexport function libChunkName(id: string) {\n  const pkgName = pathToPkgName(id);\n  return pkgName ? `_libs/${pkgName}` : undefined;\n}\n\nexport function pathToPkgName(path: string): string | undefined {\n  let pkgName = path.match(\n    /.*(?:[/\\\\])node_modules(?:[/\\\\])(?<name>@[^/\\\\]+[/\\\\][^/\\\\]+|[^/\\\\.][^/\\\\]*)/\n  )?.groups?.name;\n  if (pkgName?.endsWith(\"-nightly\")) {\n    pkgName = pkgName.slice(0, -8);\n  }\n  return pkgName;\n}\n\nexport function getChunkName(chunk: { name: string; moduleIds: string[] }, nitro: Nitro) {\n  // Known groups\n  if (chunk.name === \"rolldown-runtime\") {\n    return \"_runtime.mjs\";\n  }\n\n  // Library chunks\n  if (chunk.moduleIds.every((id) => NODE_MODULES_RE.test(id))) {\n    const chunkName = joinPkgNames(chunk.moduleIds);\n    if (chunkName.length > 30) {\n      return `${chunk.name}+[...].mjs`;\n    }\n    return `_libs/${chunkName || \"_\"}.mjs`;\n  }\n\n  // _ chunks are preserved (should be after library normalization)\n  if (chunk.name.startsWith(\"_\")) {\n    return `${chunk.name}.mjs`;\n  }\n\n  // No moduleIds\n  if (chunk.moduleIds.length === 0) {\n    return `_chunks/${chunk.name}.mjs`;\n  }\n\n  const ids = chunk.moduleIds.filter((id) => !virtualRe.test(id));\n\n  // All virtual\n  if (ids.length === 0) {\n    if (chunk.moduleIds.every((id) => id.includes(\"virtual:raw\"))) {\n      return `_raw/[name].mjs`;\n    }\n    return `_virtual/[name].mjs`;\n  }\n\n  // WASM chunk\n  if (ids.every((id) => id.endsWith(\".wasm\"))) {\n    return `_wasm/[name].mjs`;\n  }\n\n  // Chunks generate by other vite environments (we assume SSR for simplicity)\n  if (ids.every((id) => id.includes(\"vite/services\"))) {\n    return `_ssr/[name].mjs`;\n  }\n\n  // Chunks from generated code\n  if (ids.every((id) => id.startsWith(nitro.options.buildDir))) {\n    return `_build/[name].mjs`;\n  }\n\n  // Try to match user defined routes or tasks\n  const mainId = ids.at(-1);\n  if (mainId) {\n    const routeHandler = nitro.routing.routes.routes\n      .flatMap((h) => h.data)\n      .find((h) => h.handler === mainId);\n    if (routeHandler?.route) {\n      return `_routes/${routeToFsPath(routeHandler.route)}.mjs`;\n    }\n\n    const taskHandler = Object.entries(nitro.options.tasks).find(\n      ([_, task]) => task.handler === mainId\n    );\n    if (taskHandler) {\n      return `_tasks/[name].mjs`;\n    }\n  }\n\n  return `_chunks/[name].mjs`;\n}\n\nfunction joinPkgNames(moduleIds: string[]): string {\n  const names = [\n    ...new Set(\n      moduleIds\n        .map((id) => pathToPkgName(id))\n        .filter(Boolean)\n        .map((name) => name!.replace(/^@/, \"\").replace(/[/\\\\]/g, \"__\"))\n    ),\n  ].sort();\n  return names.join(\"+\");\n}\n\nexport function routeToFsPath(route: string) {\n  return (\n    route\n      .split(\"/\")\n      .slice(1)\n      .map((s) =>\n        s\n          .replace(/:(\\w+)/g, \"[$1]\")\n          .replace(/\\*+/g, \"[...]\")\n          .replace(/[^a-zA-Z0-9_.[\\]]/g, \"_\")\n      )\n      .join(\"/\") || \"index\"\n  );\n}\n"
  },
  {
    "path": "src/build/config.ts",
    "content": "import type { Nitro, NitroImportMeta } from \"nitro/types\";\nimport { defineEnv } from \"unenv\";\nimport { pkgDir } from \"nitro/meta\";\nimport { pathRegExp, toPathRegExp } from \"../utils/regex.ts\";\n\nexport type BaseBuildConfig = ReturnType<typeof baseBuildConfig>;\n\nexport function baseBuildConfig(nitro: Nitro) {\n  // prettier-ignore\n  const extensions: string[] = [\".ts\", \".mjs\", \".js\", \".json\", \".node\", \".tsx\", \".jsx\" ];\n\n  const isNodeless = nitro.options.node === false;\n\n  const importMetaInjections: NitroImportMeta = {\n    dev: nitro.options.dev,\n    preset: nitro.options.preset,\n    prerender: nitro.options.preset === \"nitro-prerender\",\n    nitro: true,\n    server: true,\n    client: false,\n    baseURL: nitro.options.baseURL,\n    _asyncContext: nitro.options.experimental.asyncContext,\n    _tasks: nitro.options.experimental.tasks,\n    _websocket: nitro.options.features.websocket ?? nitro.options.experimental.websocket,\n  };\n\n  const replacements = {\n    ...Object.fromEntries(\n      Object.entries(importMetaInjections).map(([key, val]) => [\n        `import.meta.${key}`,\n        JSON.stringify(val),\n      ])\n    ),\n    ...nitro.options.replace,\n  };\n\n  const { env } = defineEnv({\n    nodeCompat: isNodeless,\n    resolve: true,\n    presets: nitro.options.unenv,\n    overrides: {\n      alias: nitro.options.alias,\n    },\n  });\n\n  const aliases = resolveAliases({ ...env.alias });\n\n  const noExternal: RegExp[] = getNoExternals(nitro);\n\n  const ignoreWarningCodes = new Set([\n    \"EVAL\",\n    \"CIRCULAR_DEPENDENCY\",\n    \"THIS_IS_UNDEFINED\",\n    \"EMPTY_BUNDLE\",\n  ]);\n\n  return {\n    extensions,\n    isNodeless,\n    replacements,\n    env,\n    aliases,\n    noExternal,\n    ignoreWarningCodes,\n  };\n}\n\nfunction getNoExternals(nitro: Nitro): RegExp[] {\n  const noExternal: RegExp[] = [\n    /\\.[mc]?tsx?$/,\n    /^(?:[\\0#~.]|virtual:)/,\n    new RegExp(\"^\" + pathRegExp(pkgDir) + \"(?!.*node_modules)\"),\n    ...[\n      nitro.options.rootDir,\n      ...nitro.options.scanDirs.filter(\n        (dir) => dir.includes(\"node_modules\") || !dir.startsWith(nitro.options.rootDir)\n      ),\n    ].map((dir) => new RegExp(\"^\" + pathRegExp(dir) + \"(?!.*node_modules)\")),\n  ];\n\n  if (nitro.options.wasm !== false) {\n    noExternal.push(/\\.wasm$/);\n  }\n\n  if (Array.isArray(nitro.options.noExternals)) {\n    noExternal.push(\n      ...nitro.options.noExternals\n        .filter(Boolean)\n        .map((item) => toPathRegExp(item as string | RegExp))\n    );\n  }\n\n  return noExternal.sort((a, b) => a.source.length - b.source.length);\n}\n\nexport function resolveAliases(_aliases: Record<string, string>) {\n  // Sort aliases from specific to general (ie. fs/promises before fs)\n  const aliases = Object.fromEntries(\n    Object.entries(_aliases).sort(\n      ([a], [b]) => b.split(\"/\").length - a.split(\"/\").length || b.length - a.length\n    )\n  );\n  // Resolve alias values in relation to each other\n  for (const key in aliases) {\n    for (const alias in aliases) {\n      if (![\"~\", \"@\", \"#\"].includes(alias[0])) {\n        continue;\n      }\n      if (alias === \"@\" && !aliases[key].startsWith(\"@/\")) {\n        continue;\n      } // Don't resolve @foo/bar\n\n      if (aliases[key].startsWith(alias)) {\n        aliases[key] = aliases[alias] + aliases[key].slice(alias.length);\n      }\n    }\n  }\n  return aliases;\n}\n"
  },
  {
    "path": "src/build/info.ts",
    "content": "import type { Nitro, NitroBuildInfo, WorkerAddress } from \"nitro/types\";\nimport { join, relative, resolve } from \"pathe\";\nimport { version as nitroVersion } from \"nitro/meta\";\nimport { presetsWithConfig } from \"../presets/_types.gen.ts\";\nimport { writeFile } from \"../utils/fs.ts\";\nimport { mkdir, readFile, stat } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { RolldownOutput } from \"rolldown\";\nimport type { RollupOutput } from \"rollup\";\n\nconst NITRO_WELLKNOWN_DIR = \"node_modules/.nitro\";\n\nexport async function getBuildInfo(\n  root: string\n): Promise<\n  | { outputDir?: undefined; buildInfo?: undefined }\n  | { outputDir: string; buildInfo?: NitroBuildInfo }\n> {\n  const outputDir = await findLastBuildDir(root);\n\n  const isDir = await stat(outputDir)\n    .then((s) => s.isDirectory())\n    .catch(() => false);\n  if (!isDir) {\n    return {};\n  }\n\n  const buildInfo = (await readFile(resolve(outputDir, \"nitro.json\"), \"utf8\")\n    .then(JSON.parse)\n    .catch(() => undefined)) as NitroBuildInfo | undefined;\n\n  return {\n    outputDir,\n    buildInfo,\n  };\n}\n\nexport async function findLastBuildDir(root: string): Promise<string> {\n  const lastBuildLink = join(root, NITRO_WELLKNOWN_DIR, \"last-build.json\");\n  const outputDir = await readFile(lastBuildLink, \"utf8\")\n    .then(JSON.parse)\n    .then((data) => resolve(lastBuildLink, data.outputDir || \"../../../.output\"))\n    .catch(() => resolve(root, \".output\"));\n  return outputDir;\n}\n\nexport async function writeBuildInfo(\n  nitro: Nitro,\n  output: RolldownOutput | RollupOutput | undefined\n): Promise<NitroBuildInfo> {\n  const serverEntryName = output?.output?.find((o) => o.type === \"chunk\" && o.isEntry)?.fileName;\n\n  const buildInfoPath = resolve(nitro.options.output.dir, \"nitro.json\");\n  const buildInfo: NitroBuildInfo = {\n    date: new Date().toJSON(),\n    preset: nitro.options.preset,\n    framework: nitro.options.framework,\n    versions: {\n      nitro: nitroVersion,\n    },\n    serverEntry: serverEntryName\n      ? relative(nitro.options.output.dir, join(nitro.options.output.serverDir, serverEntryName))\n      : undefined,\n    publicDir: relative(\n      nitro.options.output.dir,\n      resolve(nitro.options.output.dir, nitro.options.output.publicDir)\n    ),\n    commands: {\n      preview: nitro.options.commands.preview,\n      deploy: nitro.options.commands.deploy,\n    },\n    config: {\n      ...Object.fromEntries(presetsWithConfig.map((key) => [key, nitro.options[key]])),\n    },\n  };\n\n  await writeFile(buildInfoPath, JSON.stringify(buildInfo, null, 2), true);\n\n  const lastBuild = join(nitro.options.rootDir, NITRO_WELLKNOWN_DIR, \"last-build.json\");\n  await mkdir(dirname(lastBuild), { recursive: true });\n  await writeFile(\n    lastBuild,\n    JSON.stringify({\n      outputDir: relative(lastBuild, nitro.options.output.dir),\n    })\n  );\n  return buildInfo;\n}\n\nexport async function writeDevBuildInfo(nitro: Nitro, addr?: WorkerAddress): Promise<void> {\n  const buildInfoPath = join(nitro.options.rootDir, NITRO_WELLKNOWN_DIR, \"nitro.dev.json\");\n  const buildInfo: NitroBuildInfo = {\n    date: new Date().toJSON(),\n    preset: nitro.options.preset,\n    framework: nitro.options.framework,\n    versions: {\n      nitro: nitroVersion,\n    },\n    dev: {\n      pid: process.pid,\n      workerAddress: addr,\n    },\n  };\n  await writeFile(buildInfoPath, JSON.stringify(buildInfo, null, 2));\n}\n"
  },
  {
    "path": "src/build/plugins/externals.ts",
    "content": "import type { Plugin } from \"rollup\";\nimport type { PackageJson } from \"pkg-types\";\nimport type { ExternalsTraceOptions } from \"nf3\";\n\nimport { pathToFileURL } from \"node:url\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { isAbsolute, join } from \"pathe\";\nimport { resolveModulePath } from \"exsolve\";\nimport { escapeRegExp, toPathRegExp } from \"../../utils/regex.ts\";\nimport consola from \"consola\";\n\nexport type ExternalsOptions = {\n  rootDir: string;\n  conditions: string[];\n  exclude?: (string | RegExp)[];\n  include?: (string | RegExp)[];\n  trace?: false | Omit<ExternalsTraceOptions, \"rootDir\" | \"exportConditions\" | \"traceOptions\">;\n};\n\nconst PLUGIN_NAME = \"nitro:externals\";\n\nexport function externals(opts: ExternalsOptions): Plugin {\n  const include: RegExp[] | undefined = opts?.include\n    ? opts.include.map((p) => toPathRegExp(p))\n    : undefined;\n\n  const exclude: RegExp[] = [\n    /^(?:[\\0#~.]|[a-z0-9]{2,}:)|\\?/,\n    ...(opts?.exclude || []).map((p) => toPathRegExp(p)),\n  ];\n\n  const filter = (id: string) => {\n    // Most match at least one include (if specified)\n    if (include && !include.some((r) => r.test(id))) {\n      return false;\n    }\n    // Most not match any exclude\n    if (exclude.some((r) => r.test(id))) {\n      return false;\n    }\n    return true;\n  };\n\n  const tryResolve = (id: string, from: string | undefined) =>\n    resolveModulePath(id, {\n      try: true,\n      from: from && isAbsolute(from) ? from : opts.rootDir,\n      conditions: opts.conditions,\n    });\n\n  const tracedPaths = new Set<string>();\n\n  if (include && include.length === 0) {\n    return {\n      name: PLUGIN_NAME,\n    };\n  }\n\n  return {\n    name: PLUGIN_NAME,\n    resolveId: {\n      order: \"pre\",\n      filter: { id: { exclude, include } },\n      async handler(id, importer, rOpts) {\n        // Externalize built-in modules with normalized prefix\n        if (builtinModules.includes(id)) {\n          return {\n            resolvedBy: PLUGIN_NAME,\n            external: true,\n            id: id.includes(\":\") ? id : `node:${id}`,\n          };\n        }\n\n        // Skip nested rollup-node resolutions\n        if (rOpts.custom?.[\"node-resolve\"]) {\n          return null;\n        }\n\n        // Resolve by other resolvers\n        let resolved = await this.resolve(id, importer, rOpts);\n\n        // Skip rolldown-plugin-commonjs resolver for externals\n        const cjsResolved = resolved?.meta?.commonjs?.resolved;\n        if (cjsResolved) {\n          if (!filter(cjsResolved.id)) {\n            return resolved; // Bundled and wrapped by CJS plugin\n          }\n          resolved = cjsResolved /* non-wrapped */;\n        }\n\n        // Check if not resolved or explicitly marked as excluded\n        if (!resolved?.id || !filter(resolved!.id)) {\n          return resolved;\n        }\n\n        // Normalize to absolute path\n        let resolvedPath = resolved.id;\n        if (!isAbsolute(resolvedPath)) {\n          resolvedPath = tryResolve(resolvedPath, importer) || resolvedPath;\n        }\n\n        // Tracing mode\n        if (opts.trace) {\n          let importId = toImport(id) || toImport(resolvedPath);\n          if (!importId) {\n            return resolved;\n          }\n          if (!tryResolve(importId, importer)) {\n            const guessed = await guessSubpath(resolvedPath, opts.conditions);\n            if (!guessed) {\n              return resolved;\n            }\n            importId = guessed;\n          }\n          tracedPaths.add(resolvedPath);\n          return {\n            ...resolved,\n            resolvedBy: PLUGIN_NAME,\n            external: true,\n            id: importId,\n          };\n        }\n\n        // Resolve as absolute path external\n        return {\n          ...resolved,\n          resolvedBy: PLUGIN_NAME,\n          external: true,\n          id: isAbsolute(resolvedPath)\n            ? pathToFileURL(resolvedPath).href // windows compat\n            : resolvedPath,\n        };\n      },\n    },\n    buildEnd: {\n      order: \"post\",\n      async handler() {\n        if (!opts.trace || tracedPaths.size === 0) {\n          return;\n        }\n        const { traceNodeModules } = await import(\"nf3\");\n        const traceTime = Date.now();\n        let traceFilesCount = 0;\n        let tracedPkgsCount = 0;\n        await traceNodeModules([...tracedPaths], {\n          ...opts.trace,\n          conditions: opts.conditions,\n          rootDir: opts.rootDir,\n          writePackageJson: true, // deno compat\n          hooks: {\n            tracedFiles(result) {\n              traceFilesCount = Object.keys(result).length;\n            },\n            tracedPackages: (pkgs) => {\n              tracedPkgsCount = Object.keys(pkgs).length;\n              consola.info(\n                `Tracing dependencies:\\n${Object.entries(pkgs)\n                  .map(\n                    ([name, versions]) =>\n                      `- \\`${name}\\` (${Object.keys(versions.versions).join(\", \")})`\n                  )\n                  .join(\"\\n\")}`\n              );\n            },\n          },\n        });\n        consola.success(\n          `Traced ${tracedPkgsCount} dependencies (${traceFilesCount} files) in ${Date.now() - traceTime}ms.`\n        );\n        consola.info(\n          `Ensure your production environment matches the builder OS and architecture (\\`${process.platform}-${process.arch}\\`) to avoid native module issues.`\n        );\n      },\n    },\n  };\n}\n\n// ---- Internal utils ----\n\nconst NODE_MODULES_RE =\n  /^(?<dir>.+[\\\\/]node_modules[\\\\/])(?<name>[^@\\\\/]+|@[^\\\\/]+[\\\\/][^\\\\/]+)(?:[\\\\/](?<subpath>.+))?$/;\n\nconst IMPORT_RE = /^(?!\\.)(?<name>[^@/\\\\]+|@[^/\\\\]+[/\\\\][^/\\\\]+)(?:[/\\\\](?<subpath>.+))?$/;\n\nfunction toImport(id: string): string | undefined {\n  if (isAbsolute(id)) {\n    const { name, subpath } = NODE_MODULES_RE.exec(id)?.groups || ({} as Record<string, string>);\n    if (name && subpath) {\n      return join(name, subpath);\n    }\n  } else if (IMPORT_RE.test(id)) {\n    return id;\n  }\n}\n\nfunction guessSubpath(path: string, conditions: string[]): string | undefined {\n  const { dir, name, subpath } = NODE_MODULES_RE.exec(path)?.groups || {};\n  if (!dir || !name || !subpath) {\n    return;\n  }\n  const pkgDir = join(dir, name) + \"/\";\n  const exports = getPkgJSON(pkgDir)?.exports;\n  if (!exports || typeof exports !== \"object\") {\n    return;\n  }\n  for (const e of flattenExports(exports)) {\n    if (!conditions.includes(e.condition || \"default\")) {\n      continue;\n    }\n    if (e.fsPath === subpath) {\n      return join(name, e.subpath);\n    }\n    if (e.fsPath.includes(\"*\")) {\n      const fsPathRe = new RegExp(\n        \"^\" + escapeRegExp(e.fsPath).replace(String.raw`\\*`, \"(.+?)\") + \"$\"\n      );\n      if (fsPathRe.test(subpath)) {\n        const matched = fsPathRe.exec(subpath)?.[1];\n        if (matched) {\n          return join(name, e.subpath.replace(\"*\", matched));\n        }\n      }\n    }\n  }\n}\n\nfunction getPkgJSON(dir: string): PackageJson | undefined {\n  const cache = ((getPkgJSON as any)._cache ||= new Map<string, PackageJson>());\n  if (cache.has(dir)) {\n    return cache.get(dir);\n  }\n  try {\n    const pkg = createRequire(dir)(\"./package.json\");\n    cache.set(dir, pkg);\n    return pkg;\n  } catch {\n    /* ignore */\n  }\n}\n\n// Based on mlly\nfunction flattenExports(\n  exports: Exclude<PackageJson[\"exports\"], string> = {},\n  parentSubpath = \"./\"\n): { subpath: string; fsPath: string; condition?: string }[] {\n  return Object.entries(exports).flatMap(([key, value]) => {\n    const [subpath, condition] = key.startsWith(\".\") ? [key.slice(1)] : [undefined, key];\n    const _subPath = join(parentSubpath, subpath || \"\");\n    if (typeof value === \"string\") {\n      return [{ subpath: _subPath, fsPath: value.replace(/^\\.\\//, \"\"), condition }];\n    }\n    return typeof value === \"object\" ? flattenExports(value, _subPath) : [];\n  });\n}\n"
  },
  {
    "path": "src/build/plugins/oxc.ts",
    "content": "import type { MinifyOptions } from \"rolldown/experimental\";\nimport type { OXCOptions } from \"nitro/types\";\nimport type { Plugin } from \"rollup\";\n\nexport async function oxc(\n  options: OXCOptions & { sourcemap: boolean; minify: boolean | MinifyOptions }\n): Promise<Plugin> {\n  const { minifySync, transformSync } = await import(\"rolldown/utils\");\n  return {\n    name: \"nitro:oxc\",\n    transform: {\n      filter: {\n        id: /^(?!.*\\/node_modules\\/).*\\.m?[jt]sx?$/,\n      },\n      handler(code, id) {\n        const res = transformSync(id, code, {\n          sourcemap: options.sourcemap,\n          tsconfig: false,\n          ...options.transform,\n        });\n        if (res.errors?.length > 0) {\n          this.error(res.errors.join(\"\\n\"));\n        }\n        return res;\n      },\n    },\n    renderChunk(code, chunk) {\n      if (options.minify) {\n        return minifySync(chunk.fileName, code, {\n          sourcemap: options.sourcemap,\n          ...(typeof options.minify === \"object\" ? options.minify : {}),\n        });\n      }\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/plugins/raw.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport mime from \"mime\";\nimport type { Plugin } from \"rollup\";\n\nconst HELPER_ID = \"virtual:nitro-raw-helpers\";\nconst RESOLVED_PREFIX = \"virtual:nitro:raw:\";\nconst PREFIX = \"raw:\";\n\nexport function raw(): Plugin {\n  return {\n    name: \"nitro:raw\",\n    resolveId: {\n      order: \"pre\",\n      filter: {\n        id: [new RegExp(`^${HELPER_ID}$`), new RegExp(`^${PREFIX}`)],\n      },\n      async handler(id, importer, resolveOpts) {\n        if (id === HELPER_ID) {\n          return id;\n        }\n        if (id.startsWith(PREFIX)) {\n          const resolvedId = (await this.resolve(id.slice(PREFIX.length), importer, resolveOpts))\n            ?.id;\n          if (!resolvedId) {\n            return null;\n          }\n          return { id: RESOLVED_PREFIX + resolvedId };\n        }\n      },\n    },\n    load: {\n      order: \"pre\",\n      filter: {\n        id: [new RegExp(`^${HELPER_ID}$`), new RegExp(`^${RESOLVED_PREFIX}`)],\n      },\n      handler(id) {\n        if (id === HELPER_ID) {\n          return getHelpers();\n        }\n        if (id.startsWith(RESOLVED_PREFIX)) {\n          // this.addWatchFile(id.substring(RESOLVED_PREFIX.length));\n          return fsp.readFile(id.slice(RESOLVED_PREFIX.length), isBinary(id) ? \"binary\" : \"utf8\");\n        }\n      },\n    },\n    transform: {\n      order: \"pre\",\n      filter: {\n        id: new RegExp(`^${RESOLVED_PREFIX}`),\n      },\n      handler(code, id) {\n        const path = id.slice(RESOLVED_PREFIX.length);\n        if (isBinary(id)) {\n          const serialized = Buffer.from(code, \"binary\").toString(\"base64\");\n          return {\n            code: `import {base64ToUint8Array } from \"${HELPER_ID}\" \\n export default base64ToUint8Array(\"${serialized}\")`,\n            map: rawAssetMap(path),\n          };\n        }\n        return {\n          code: `export default ${JSON.stringify(code)}`,\n          map: rawAssetMap(path),\n          moduleType: \"js\",\n        };\n      },\n    },\n  };\n}\n\nfunction isBinary(id: string) {\n  const idMime = mime.getType(id) || \"\";\n  if (idMime.startsWith(\"text/\")) {\n    return false;\n  }\n  if (/application\\/(json|sql|xml|yaml)/.test(idMime)) {\n    return false;\n  }\n  return true;\n}\n\nfunction getHelpers() {\n  return /* js */ `\nexport function base64ToUint8Array(str) {\n  const data = atob(str);\n  const size = data.length;\n  const bytes = new Uint8Array(size);\n  for (let i = 0; i < size; i++) {\n    bytes[i] = data.charCodeAt(i);\n  }\n  return bytes;\n}\n  `;\n}\n\nfunction rawAssetMap(id: string) {\n  return {\n    version: 3,\n    file: id,\n    sources: [id],\n    sourcesContent: [],\n    names: [],\n    mappings: \"\",\n  };\n}\n"
  },
  {
    "path": "src/build/plugins/route-meta.ts",
    "content": "import { readFile } from \"node:fs/promises\";\nimport { isAbsolute } from \"pathe\";\nimport type { Expression, Literal } from \"estree\";\nimport type { Nitro, NitroEventHandler } from \"nitro/types\";\nimport type { Plugin } from \"rollup\";\nimport { escapeRegExp } from \"../../utils/regex.ts\";\n\nconst PREFIX = \"\\0nitro:route-meta:\";\n\nexport async function routeMeta(nitro: Nitro) {\n  const { transformSync } = await import(\"rolldown/utils\");\n  return {\n    name: \"nitro:route-meta\",\n    resolveId: {\n      // eslint-disable-next-line no-control-regex\n      filter: { id: /^(?!\\u0000)(.+)\\?meta$/ },\n      async handler(id, importer, resolveOpts) {\n        if (id.endsWith(\"?meta\")) {\n          const resolved = await this.resolve(id.replace(\"?meta\", \"\"), importer, resolveOpts);\n          if (!resolved) {\n            return;\n          }\n          return PREFIX + resolved.id;\n        }\n      },\n    },\n    load: {\n      filter: {\n        id: new RegExp(`^${escapeRegExp(PREFIX)}`),\n      },\n      handler(id) {\n        if (id.startsWith(PREFIX)) {\n          const fullPath = id.slice(PREFIX.length);\n          if (isAbsolute(fullPath)) {\n            return readFile(fullPath, { encoding: \"utf8\" });\n          } else {\n            return \"export default undefined;\";\n          }\n        }\n      },\n    },\n    transform: {\n      filter: {\n        id: new RegExp(`^${escapeRegExp(PREFIX)}`),\n      },\n      async handler(code, id) {\n        let meta: NitroEventHandler[\"meta\"] | null = null;\n\n        try {\n          const transformRes = transformSync(id, code, { tsconfig: false });\n          if (transformRes.errors?.length > 0) {\n            for (const error of transformRes.errors) {\n              this.warn(error);\n            }\n            return {\n              code: `export default {};`,\n              map: null,\n            };\n          }\n\n          const ast = this.parse(transformRes.code);\n          for (const node of ast.body) {\n            if (\n              node.type === \"ExpressionStatement\" &&\n              node.expression.type === \"CallExpression\" &&\n              node.expression.callee.type === \"Identifier\" &&\n              node.expression.callee.name === \"defineRouteMeta\" &&\n              node.expression.arguments.length === 1\n            ) {\n              meta = astToObject(node.expression.arguments[0] as any);\n              break;\n            }\n          }\n        } catch (error) {\n          nitro.logger.warn(`[handlers-meta] Cannot extra route meta for: ${id}: ${error}`);\n        }\n\n        return {\n          code: `export default ${JSON.stringify(meta)};`,\n          map: null,\n        };\n      },\n    },\n  } satisfies Plugin;\n}\n\nfunction astToObject(node: Expression | Literal): any {\n  switch (node.type) {\n    case \"ObjectExpression\": {\n      const obj: Record<string, any> = {};\n      for (const prop of node.properties) {\n        if (prop.type === \"Property\") {\n          const key = (prop.key as any).name ?? (prop.key as any).value;\n          obj[key] = astToObject(prop.value as any);\n        }\n      }\n      return obj;\n    }\n    case \"ArrayExpression\": {\n      return node.elements.map((el) => astToObject(el as any)).filter((obj) => obj !== undefined);\n    }\n    case \"Literal\": {\n      return node.value;\n    }\n    // No default\n  }\n}\n"
  },
  {
    "path": "src/build/plugins/server-main.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { Plugin } from \"rollup\";\n\nexport function serverMain(nitro: Nitro): Plugin {\n  return {\n    name: \"nitro:server-main\",\n    renderChunk(code, chunk) {\n      if (chunk.isEntry) {\n        return {\n          code: `globalThis.__nitro_main__ = import.meta.url; ${code}`,\n          map: null,\n        };\n      }\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/plugins/sourcemap-min.ts",
    "content": "import type { ExistingRawSourceMap, Plugin } from \"rollup\";\n\nexport function sourcemapMinify() {\n  return {\n    name: \"nitro:sourcemap-minify\",\n    generateBundle(_options, bundle) {\n      for (const [key, asset] of Object.entries(bundle)) {\n        // Only process sourcemaps\n        if (!key.endsWith(\".map\") || !(\"source\" in asset) || typeof asset.source !== \"string\") {\n          continue;\n        }\n\n        // Parse sourcemap\n        const sourcemap: ExistingRawSourceMap = JSON.parse(asset.source);\n\n        // Remove sourcesContent\n        delete sourcemap.sourcesContent;\n\n        // Remove x_google_ignoreList\n        delete sourcemap.x_google_ignoreList;\n\n        if ((sourcemap.sources || []).every((s) => s.includes(\"node_modules\"))) {\n          sourcemap.mappings = \"\"; // required key\n        }\n\n        asset.source = JSON.stringify(sourcemap);\n      }\n    },\n  } satisfies Plugin;\n}\n"
  },
  {
    "path": "src/build/plugins/virtual.ts",
    "content": "import type { Plugin, ResolvedId } from \"rollup\";\nimport { pathRegExp } from \"../../utils/regex.ts\";\nimport { runtimeDependencies, runtimeDir } from \"nitro/meta\";\n\nexport type VirtualModule = {\n  id: string;\n  moduleSideEffects?: boolean;\n  template: string | (() => string | Promise<string>);\n};\n\nexport function virtual(input: VirtualModule[]): Plugin {\n  const modules = new Map<\n    string,\n    { module: VirtualModule; render: () => string | Promise<string> }\n  >();\n  for (const mod of input) {\n    const render = () => (typeof mod.template === \"function\" ? mod.template() : mod.template);\n    modules.set(mod.id, { module: mod, render });\n  }\n\n  const include: RegExp[] = [/^#nitro\\/virtual/];\n\n  const extraIds = [...modules.keys()].filter((key) => !key.startsWith(\"#nitro/virtual\"));\n  if (extraIds.length > 0) {\n    include.push(new RegExp(`^(${extraIds.map((id) => pathRegExp(id)).join(\"|\")})$`));\n  }\n\n  return {\n    name: \"nitro:virtual\",\n    api: {\n      modules,\n    },\n    resolveId: {\n      order: \"pre\",\n      filter: { id: include },\n      handler: (id) => {\n        const mod = modules.get(id);\n        if (mod) {\n          return {\n            id,\n            moduleSideEffects: mod.module.moduleSideEffects ?? false,\n          };\n        }\n      },\n    },\n    load: {\n      order: \"pre\",\n      filter: { id: include },\n      handler: async (id) => {\n        const mod = modules.get(id);\n        if (!mod) {\n          throw new Error(`Virtual module ${id} not found.`);\n        }\n        return {\n          code: await mod.render(),\n          map: null,\n        };\n      },\n    },\n  };\n}\n\nexport function virtualDeps(): Plugin {\n  const cache = new Map<string, ResolvedId | null | Promise<ResolvedId | null>>();\n\n  return {\n    name: \"nitro:virtual-deps\",\n    resolveId: {\n      order: \"pre\",\n      filter: {\n        id: new RegExp(`^(#nitro|${runtimeDependencies.map((dep) => pathRegExp(dep)).join(\"|\")})`),\n      },\n      handler(id, importer) {\n        // https://github.com/rolldown/rolldown/issues/7529\n        if (!importer || !importer.startsWith(\"#nitro/virtual\")) {\n          return;\n        }\n        let resolved = cache.get(id);\n        if (!resolved) {\n          resolved = this.resolve(id, runtimeDir)\n            .then((_resolved) => {\n              cache.set(id, _resolved);\n              return _resolved;\n            })\n            .catch((error) => {\n              cache.delete(id);\n              throw error;\n            });\n        }\n        return resolved;\n      },\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/plugins.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { Plugin } from \"rollup\";\nimport type { BaseBuildConfig } from \"./config.ts\";\n\nimport { virtualTemplates } from \"./virtual/_all.ts\";\nimport replace from \"@rollup/plugin-replace\";\nimport { unwasm } from \"unwasm/plugin\";\nimport { routeMeta } from \"./plugins/route-meta.ts\";\nimport { serverMain } from \"./plugins/server-main.ts\";\nimport { virtual, virtualDeps } from \"./plugins/virtual.ts\";\nimport { sourcemapMinify } from \"./plugins/sourcemap-min.ts\";\nimport { raw } from \"./plugins/raw.ts\";\nimport { externals } from \"./plugins/externals.ts\";\n\nexport async function baseBuildPlugins(nitro: Nitro, base: BaseBuildConfig) {\n  const plugins: Plugin[] = [];\n\n  // Virtual\n  const virtualPlugin = virtual(virtualTemplates(nitro, [...base.env.polyfill]));\n  nitro.vfs = virtualPlugin.api.modules;\n  plugins.push(virtualPlugin, virtualDeps());\n\n  // Auto imports\n  if (nitro.options.imports) {\n    const unimportPlugin = await import(\"unimport/unplugin\");\n    plugins.push(unimportPlugin.default.rollup(nitro.options.imports) as Plugin);\n  }\n\n  // WASM loader\n  if (nitro.options.wasm !== false) {\n    plugins.push(unwasm(nitro.options.wasm || {}));\n  }\n\n  // Inject globalThis.__server_main__\n  plugins.push(serverMain(nitro));\n\n  // Raw Imports\n  plugins.push(raw());\n\n  // Route meta\n  if (nitro.options.experimental.openAPI) {\n    plugins.push(await routeMeta(nitro));\n  }\n\n  // Replace\n  plugins.push(\n    (replace as unknown as typeof replace.default)({\n      preventAssignment: true,\n      values: base.replacements,\n    })\n  );\n\n  // Externals (require Node.js compatible resolution)\n  if (nitro.options.node && nitro.options.noExternals !== true) {\n    const isDevOrPrerender = nitro.options.dev || nitro.options.preset === \"nitro-prerender\";\n    const { NodeNativePackages, NonBundleablePackages } = await import(\"nf3/db\");\n    const traceDeps = [\n      ...new Set([\n        ...NodeNativePackages,\n        ...NonBundleablePackages,\n        ...(nitro.options.traceDeps || []),\n      ]),\n    ];\n    plugins.push(\n      externals({\n        rootDir: nitro.options.rootDir,\n        conditions: nitro.options.exportConditions!,\n        exclude: [...base.noExternal],\n        include: isDevOrPrerender\n          ? undefined\n          : [\n              new RegExp(\n                `^(?:${traceDeps.join(\"|\")})|[/\\\\\\\\]node_modules[/\\\\\\\\](?:${traceDeps.join(\"|\")})(?:[/\\\\\\\\])`\n              ),\n            ],\n        trace: isDevOrPrerender ? false : { outDir: nitro.options.output.serverDir },\n      })\n    );\n  }\n\n  // Sourcemap minify\n  if (\n    nitro.options.sourcemap &&\n    !nitro.options.dev &&\n    nitro.options.experimental.sourcemapMinify !== false\n  ) {\n    plugins.push(sourcemapMinify());\n  }\n\n  return plugins;\n}\n"
  },
  {
    "path": "src/build/prepare.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport type { Nitro } from \"nitro/types\";\n\nexport async function prepare(nitro: Nitro) {\n  await prepareDir(nitro.options.output.dir);\n  if (!nitro.options.noPublicDir) {\n    await prepareDir(nitro.options.output.publicDir);\n  }\n  if (!nitro.options.static) {\n    await prepareDir(nitro.options.output.serverDir);\n  }\n}\n\nasync function prepareDir(dir: string) {\n  await fsp.rm(dir, { recursive: true, force: true });\n  await fsp.mkdir(dir, { recursive: true });\n}\n"
  },
  {
    "path": "src/build/rolldown/build.ts",
    "content": "import { getRolldownConfig } from \"./config.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { watchDev } from \"./dev.ts\";\nimport { buildProduction } from \"./prod.ts\";\n\nexport async function rolldownBuild(nitro: Nitro) {\n  await nitro.hooks.callHook(\"build:before\", nitro);\n  const config = await getRolldownConfig(nitro);\n  await nitro.hooks.callHook(\"rollup:before\", nitro, config as any);\n  return nitro.options.dev ? watchDev(nitro, config) : buildProduction(nitro, config);\n}\n"
  },
  {
    "path": "src/build/rolldown/config.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { OutputOptions, RolldownOptions, RolldownPlugin } from \"rolldown\";\nimport { baseBuildConfig } from \"../config.ts\";\nimport { baseBuildPlugins } from \"../plugins.ts\";\nimport { builtinModules } from \"node:module\";\nimport { defu } from \"defu\";\nimport { getChunkName, libChunkName, NODE_MODULES_RE } from \"../chunks.ts\";\n\nexport const getRolldownConfig = async (nitro: Nitro): Promise<RolldownOptions> => {\n  const base = baseBuildConfig(nitro);\n\n  const tsc = nitro.options.typescript.tsConfig?.compilerOptions;\n\n  let config: RolldownOptions = {\n    platform: nitro.options.node ? \"node\" : \"neutral\",\n    cwd: nitro.options.rootDir,\n    input: nitro.options.entry,\n    external: [...base.env.external, ...builtinModules, ...builtinModules.map((m) => `node:${m}`)],\n    plugins: [...((await baseBuildPlugins(nitro, base)) as RolldownPlugin[])],\n    resolve: {\n      alias: base.aliases,\n      extensions: base.extensions,\n      conditionNames: nitro.options.exportConditions,\n    },\n    transform: {\n      inject: base.env.inject as Record<string, string>,\n      jsx: {\n        runtime: tsc?.jsx === \"react\" ? \"classic\" : \"automatic\",\n        pragma: tsc?.jsxFactory,\n        pragmaFrag: tsc?.jsxFragmentFactory,\n        importSource: tsc?.jsxImportSource,\n        development: nitro.options.dev,\n      },\n    },\n    onwarn(warning, warn) {\n      if (!base.ignoreWarningCodes.has(warning.code || \"\")) {\n        console.log(warning.code);\n        warn(warning);\n      }\n    },\n    treeshake: {\n      moduleSideEffects(id) {\n        return nitro.options.moduleSideEffects.some((p) => id.startsWith(p));\n      },\n    },\n    optimization: {\n      inlineConst: true,\n    },\n    output: {\n      format: \"esm\",\n      entryFileNames: \"index.mjs\",\n      chunkFileNames: (chunk) => getChunkName(chunk, nitro),\n      codeSplitting: {\n        groups: [{ test: NODE_MODULES_RE, name: (id) => libChunkName(id) }],\n      },\n      dir: nitro.options.output.serverDir,\n      inlineDynamicImports: nitro.options.inlineDynamicImports,\n      // https://github.com/rolldown/rolldown/issues/7235\n      minify: nitro.options.minify ? true : \"dce-only\",\n      sourcemap: nitro.options.sourcemap,\n      sourcemapIgnoreList(relativePath) {\n        return relativePath.includes(\"node_modules\");\n      },\n    },\n  } satisfies RolldownOptions;\n\n  config = defu(\n    nitro.options.rolldownConfig,\n    nitro.options.rollupConfig as RolldownOptions,\n    config\n  );\n\n  const outputConfig = config.output as OutputOptions;\n  if (outputConfig.inlineDynamicImports || outputConfig.format === \"iife\") {\n    delete outputConfig.inlineDynamicImports;\n    outputConfig.codeSplitting = false;\n  }\n\n  return config as RolldownOptions;\n};\n"
  },
  {
    "path": "src/build/rolldown/dev.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { RolldownWatcher, RolldownOptions } from \"rolldown\";\nimport { watch as chokidarWatch } from \"chokidar\";\nimport { basename, join } from \"pathe\";\nimport { debounce } from \"perfect-debounce\";\nimport { scanHandlers } from \"../../scan.ts\";\nimport { writeTypes } from \"../types.ts\";\nimport { formatCompatibilityDate } from \"compatx\";\n\nexport async function watchDev(nitro: Nitro, config: RolldownOptions) {\n  const rolldown = await import(\"rolldown\");\n\n  let watcher: RolldownWatcher;\n\n  async function load() {\n    if (watcher) {\n      await watcher.close();\n    }\n    await scanHandlers(nitro);\n    nitro.routing.sync();\n    watcher = startWatcher(nitro, config);\n    await writeTypes(nitro);\n  }\n  const reload = debounce(load);\n\n  const scanDirs = nitro.options.scanDirs.flatMap((dir) => [\n    join(dir, nitro.options.apiDir || \"api\"),\n    join(dir, nitro.options.routesDir || \"routes\"),\n    join(dir, \"middleware\"),\n    join(dir, \"plugins\"),\n    join(dir, \"modules\"),\n  ]);\n\n  const watchReloadEvents = new Set([\"add\", \"addDir\", \"unlink\", \"unlinkDir\"]);\n  const scanDirsWatcher = chokidarWatch(scanDirs, {\n    ignoreInitial: true,\n  }).on(\"all\", (event) => {\n    if (watchReloadEvents.has(event)) {\n      reload();\n    }\n  });\n\n  const serverEntryRe = /^server\\.[mc]?[jt]sx?$/;\n  const rootDirWatcher = chokidarWatch(nitro.options.rootDir, {\n    ignoreInitial: true,\n    depth: 0,\n  }).on(\"all\", (event, path) => {\n    if (watchReloadEvents.has(event) && serverEntryRe.test(basename(path))) {\n      reload();\n    }\n  });\n\n  nitro.hooks.hook(\"close\", () => {\n    watcher.close();\n    scanDirsWatcher.close();\n    rootDirWatcher.close();\n  });\n\n  nitro.hooks.hook(\"rollup:reload\", () => reload());\n\n  nitro.logger.info(\n    `Starting dev watcher (builder: \\`rolldown\\`, preset: \\`${nitro.options.preset}\\`, compatibility date: \\`${formatCompatibilityDate(nitro.options.compatibilityDate)}\\`)`\n  );\n\n  await load();\n\n  function startWatcher(nitro: Nitro, config: RolldownOptions) {\n    const watcher = rolldown.watch(config);\n\n    let start: number;\n\n    watcher.on(\"event\", (event) => {\n      // START > BUNDLE_START > BUNDLE_END > END\n      // START > BUNDLE_START > ERROR > END\n      switch (event.code) {\n        case \"START\": {\n          start = Date.now();\n          nitro.hooks.callHook(\"dev:start\");\n          break;\n        }\n        case \"BUNDLE_END\": {\n          nitro.hooks.callHook(\"compiled\", nitro);\n          if (nitro.options.logging.buildSuccess) {\n            nitro.logger.success(`Server built`, start ? `in ${Date.now() - start}ms` : \"\");\n          }\n          nitro.hooks.callHook(\"dev:reload\");\n          break;\n        }\n        case \"ERROR\": {\n          nitro.logger.error(event.error);\n          nitro.hooks.callHook(\"dev:error\", event.error);\n        }\n      }\n    });\n\n    return watcher;\n  }\n}\n"
  },
  {
    "path": "src/build/rolldown/prod.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { OutputOptions, RolldownOptions } from \"rolldown\";\nimport { formatCompatibilityDate } from \"compatx\";\n\nimport { relative } from \"pathe\";\nimport { scanHandlers } from \"../../scan.ts\";\nimport { generateFSTree } from \"../../utils/fs-tree.ts\";\nimport { writeTypes } from \"../types.ts\";\nimport { writeBuildInfo } from \"../info.ts\";\nimport type { RolldownOutput } from \"rolldown\";\n\nexport async function buildProduction(nitro: Nitro, config: RolldownOptions) {\n  const rolldown = await import(\"rolldown\");\n\n  const buildStartTime = Date.now();\n\n  await scanHandlers(nitro);\n  await writeTypes(nitro);\n\n  let output: RolldownOutput | undefined;\n  if (!nitro.options.static) {\n    nitro.logger.info(\n      `Building server (builder: \\`rolldown\\`, preset: \\`${nitro.options.preset}\\`, compatibility date: \\`${formatCompatibilityDate(nitro.options.compatibilityDate)}\\`)`\n    );\n    const build = await rolldown.rolldown(config);\n    output = (await build.write(config.output as OutputOptions)) as RolldownOutput;\n  }\n\n  const buildInfo = await writeBuildInfo(nitro, output);\n\n  if (!nitro.options.static) {\n    if (nitro.options.logging.buildSuccess) {\n      nitro.logger.success(`Server built in ${Date.now() - buildStartTime}ms`);\n    }\n    if (nitro.options.logLevel > 1) {\n      process.stdout.write(\n        (await generateFSTree(nitro.options.output.serverDir, {\n          compressedSizes: nitro.options.logging.compressedSizes,\n        })) || \"\"\n      );\n    }\n  }\n\n  await nitro.hooks.callHook(\"compiled\", nitro);\n\n  // Show deploy and preview hints\n  const rOutput = relative(process.cwd(), nitro.options.output.dir);\n  const rewriteRelativePaths = (input: string) => {\n    return input.replace(/([\\s:])\\.\\/(\\S*)/g, `$1${rOutput}/$2`);\n  };\n  nitro.logger.success(\"You can preview this build using `npx nitro preview`\");\n  if (buildInfo.commands!.deploy) {\n    nitro.logger.success(\n      rewriteRelativePaths(\"You can deploy this build using `npx nitro deploy --prebuilt`\")\n    );\n  }\n}\n"
  },
  {
    "path": "src/build/rollup/build.ts",
    "content": "import { getRollupConfig } from \"./config.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { watchDev } from \"./dev.ts\";\nimport { buildProduction } from \"./prod.ts\";\n\nexport async function rollupBuild(nitro: Nitro) {\n  await nitro.hooks.callHook(\"build:before\", nitro);\n  const config = await getRollupConfig(nitro);\n  await nitro.hooks.callHook(\"rollup:before\", nitro, config);\n  return nitro.options.dev ? watchDev(nitro, config) : buildProduction(nitro, config);\n}\n"
  },
  {
    "path": "src/build/rollup/config.ts",
    "content": "import type { Nitro, RollupConfig } from \"nitro/types\";\nimport { defu } from \"defu\";\nimport alias from \"@rollup/plugin-alias\";\nimport commonjs from \"@rollup/plugin-commonjs\";\nimport inject from \"@rollup/plugin-inject\";\nimport json from \"@rollup/plugin-json\";\nimport { nodeResolve } from \"@rollup/plugin-node-resolve\";\nimport { oxc } from \"../plugins/oxc.ts\";\nimport { baseBuildConfig } from \"../config.ts\";\nimport { baseBuildPlugins } from \"../plugins.ts\";\nimport { getChunkName, libChunkName, NODE_MODULES_RE } from \"../chunks.ts\";\n\nexport const getRollupConfig = async (nitro: Nitro): Promise<RollupConfig> => {\n  const base = baseBuildConfig(nitro);\n\n  const tsc = nitro.options.typescript.tsConfig?.compilerOptions;\n\n  let config: RollupConfig = {\n    input: nitro.options.entry,\n    external: [...base.env.external],\n    plugins: [\n      ...(await baseBuildPlugins(nitro, base)),\n      await oxc({\n        sourcemap: !!nitro.options.sourcemap,\n        minify: nitro.options.minify ? { ...nitro.options.oxc?.minify } : false,\n        transform: {\n          target: \"esnext\",\n          // @ts-expect-error TODO: does option exists?\n          cwd: nitro.options.rootDir,\n          ...nitro.options.oxc?.transform,\n          jsx: {\n            runtime: tsc?.jsx === \"react\" ? \"classic\" : \"automatic\",\n            pragma: tsc?.jsxFactory,\n            pragmaFrag: tsc?.jsxFragmentFactory,\n            importSource: tsc?.jsxImportSource,\n            development: nitro.options.dev,\n            ...nitro.options.oxc?.transform?.jsx,\n          },\n        },\n      }),\n      alias({ entries: base.aliases }),\n      nodeResolve({\n        extensions: base.extensions,\n        preferBuiltins: !!nitro.options.node,\n        rootDir: nitro.options.rootDir,\n        exportConditions: nitro.options.exportConditions,\n      }),\n      (commonjs as unknown as typeof commonjs.default)({\n        ...nitro.options.commonJS,\n      }),\n      (json as unknown as typeof json.default)(),\n      (inject as unknown as typeof inject.default)(base.env.inject),\n    ],\n    onwarn(warning, rollupWarn) {\n      if (!base.ignoreWarningCodes.has(warning.code || \"\")) {\n        rollupWarn(warning);\n      }\n    },\n    treeshake: {\n      moduleSideEffects(id) {\n        return nitro.options.moduleSideEffects.some((p) => id.startsWith(p));\n      },\n    },\n    output: {\n      format: \"esm\",\n      entryFileNames: \"index.mjs\",\n      chunkFileNames: (chunk) => getChunkName(chunk, nitro),\n      dir: nitro.options.output.serverDir,\n      inlineDynamicImports: nitro.options.inlineDynamicImports,\n      generatedCode: { constBindings: true },\n      sourcemap: nitro.options.sourcemap,\n      sourcemapExcludeSources: true,\n      sourcemapIgnoreList: (id) => id.includes(\"node_modules\"),\n      manualChunks(id: string) {\n        if (NODE_MODULES_RE.test(id)) {\n          return libChunkName(id);\n        }\n      },\n    },\n  } satisfies RollupConfig;\n\n  config = defu(nitro.options.rollupConfig as any, config);\n\n  const outputConfig = config.output as NonNullable<RollupConfig[\"output\"]>;\n  if (outputConfig.inlineDynamicImports || outputConfig.format === \"iife\") {\n    delete outputConfig.manualChunks;\n  }\n\n  return config;\n};\n"
  },
  {
    "path": "src/build/rollup/dev.ts",
    "content": "import type { Nitro, RollupConfig } from \"nitro/types\";\nimport type { RollupWatcher } from \"rollup\";\nimport { watch as chokidarWatch } from \"chokidar\";\nimport { defu } from \"defu\";\nimport { basename, join } from \"pathe\";\nimport { debounce } from \"perfect-debounce\";\nimport { scanHandlers } from \"../../scan.ts\";\nimport { formatRollupError } from \"./error.ts\";\nimport { writeTypes } from \"../types.ts\";\nimport { formatCompatibilityDate } from \"compatx\";\n\nexport async function watchDev(nitro: Nitro, rollupConfig: RollupConfig) {\n  const rollup = await import(\"rollup\");\n\n  let rollupWatcher: RollupWatcher;\n\n  async function load() {\n    if (rollupWatcher) {\n      await rollupWatcher.close();\n    }\n    await scanHandlers(nitro);\n    nitro.routing.sync();\n    rollupWatcher = startRollupWatcher(nitro, rollupConfig);\n    await writeTypes(nitro);\n  }\n  const reload = debounce(load);\n\n  const scanDirs = nitro.options.scanDirs.flatMap((dir) => [\n    join(dir, nitro.options.apiDir || \"api\"),\n    join(dir, nitro.options.routesDir || \"routes\"),\n    join(dir, \"middleware\"),\n    join(dir, \"plugins\"),\n    join(dir, \"modules\"),\n  ]);\n\n  const watchReloadEvents = new Set([\"add\", \"addDir\", \"unlink\", \"unlinkDir\"]);\n  const scanDirsWatcher = chokidarWatch(scanDirs, {\n    ignoreInitial: true,\n  }).on(\"all\", (event, path, stat) => {\n    if (watchReloadEvents.has(event)) {\n      reload();\n    }\n  });\n\n  const serverEntryRe = /^server\\.[mc]?[jt]sx?$/;\n  const rootDirWatcher = chokidarWatch(nitro.options.rootDir, {\n    ignoreInitial: true,\n    depth: 0,\n  }).on(\"all\", (event, path) => {\n    if (watchReloadEvents.has(event) && serverEntryRe.test(basename(path))) {\n      reload();\n    }\n  });\n\n  nitro.hooks.hook(\"close\", () => {\n    rollupWatcher.close();\n    scanDirsWatcher.close();\n    rootDirWatcher.close();\n  });\n\n  nitro.hooks.hook(\"rollup:reload\", () => reload());\n\n  nitro.logger.info(\n    `Starting dev watcher (builder: \\`rollup\\`, preset: \\`${nitro.options.preset}\\`, compatibility date: \\`${formatCompatibilityDate(nitro.options.compatibilityDate)}\\`)`\n  );\n\n  await load();\n\n  function startRollupWatcher(nitro: Nitro, rollupConfig: RollupConfig) {\n    const watcher = rollup.watch(\n      defu(rollupConfig, {\n        watch: {\n          chokidar: nitro.options.watchOptions,\n        },\n      })\n    );\n    let start: number;\n\n    watcher.on(\"event\", (event) => {\n      // START > BUNDLE_START > BUNDLE_END > END\n      // START > BUNDLE_START > ERROR > END\n      switch (event.code) {\n        case \"START\": {\n          start = Date.now();\n          nitro.hooks.callHook(\"dev:start\");\n          break;\n        }\n        case \"BUNDLE_END\": {\n          nitro.hooks.callHook(\"compiled\", nitro);\n          if (nitro.options.logging.buildSuccess) {\n            nitro.logger.success(`Server built`, start ? `in ${Date.now() - start}ms` : \"\");\n          }\n          nitro.hooks.callHook(\"dev:reload\");\n          break;\n        }\n        case \"ERROR\": {\n          nitro.logger.error(formatRollupError(event.error));\n          nitro.hooks.callHook(\"dev:error\", event.error);\n        }\n      }\n    });\n\n    return watcher;\n  }\n}\n"
  },
  {
    "path": "src/build/rollup/error.ts",
    "content": "import { isAbsolute, relative } from \"pathe\";\nimport type rollup from \"rollup\";\n\nexport function formatRollupError(_error: rollup.RollupError) {\n  try {\n    const logs: string[] = [_error.toString()];\n    const errors = (_error as any)?.errors || [_error as rollup.RollupError];\n    for (const error of errors) {\n      const id = (error as any).path || error.id || (_error as rollup.RollupError).id;\n      let path = isAbsolute(id) ? relative(process.cwd(), id) : id;\n      const location = (error as rollup.RollupError).loc;\n      if (location) {\n        path += `:${location.line}:${location.column}`;\n      }\n      const text = (error as rollup.RollupError).frame;\n      logs.push(`Rollup error while processing \\`${path}\\`` + text ? \"\\n\\n\" + text : \"\");\n    }\n    return logs.join(\"\\n\");\n  } catch {\n    return _error?.toString();\n  }\n}\n"
  },
  {
    "path": "src/build/rollup/prod.ts",
    "content": "import type { Nitro, RollupConfig } from \"nitro/types\";\nimport { formatCompatibilityDate } from \"compatx\";\nimport { scanHandlers } from \"../../scan.ts\";\nimport { generateFSTree } from \"../../utils/fs-tree.ts\";\nimport { writeTypes } from \"../types.ts\";\nimport { writeBuildInfo } from \"../info.ts\";\nimport { formatRollupError } from \"./error.ts\";\nimport type { RollupOutput } from \"rollup\";\n\nexport async function buildProduction(nitro: Nitro, rollupConfig: RollupConfig) {\n  const rollup = await import(\"rollup\");\n\n  const buildStartTime = Date.now();\n\n  await scanHandlers(nitro);\n  await writeTypes(nitro);\n\n  let output: RollupOutput | undefined;\n  if (!nitro.options.static) {\n    nitro.logger.info(\n      `Building server (builder: \\`rollup\\`, preset: \\`${nitro.options.preset}\\`, compatibility date: \\`${formatCompatibilityDate(nitro.options.compatibilityDate)}\\`)`\n    );\n    const build = await rollup.rollup(rollupConfig).catch((error) => {\n      nitro.logger.error(formatRollupError(error));\n      throw error;\n    });\n\n    output = await build.write(rollupConfig.output!);\n  }\n\n  const buildInfo = await writeBuildInfo(nitro, output);\n\n  if (!nitro.options.static) {\n    if (nitro.options.logging.buildSuccess) {\n      nitro.logger.success(`Server built in ${Date.now() - buildStartTime}ms`);\n    }\n    if (nitro.options.logLevel > 1) {\n      process.stdout.write(\n        (await generateFSTree(nitro.options.output.serverDir, {\n          compressedSizes: nitro.options.logging.compressedSizes,\n        })) || \"\"\n      );\n    }\n  }\n\n  await nitro.hooks.callHook(\"compiled\", nitro);\n\n  // Show deploy and preview hints\n  nitro.logger.success(\"You can preview this build using `npx nitro preview`\");\n  if (buildInfo.commands!.deploy) {\n    nitro.logger.success(\"You can deploy this build using `npx nitro deploy --prebuilt`\");\n  }\n}\n"
  },
  {
    "path": "src/build/types.ts",
    "content": "import { existsSync, promises as fsp } from \"node:fs\";\nimport { defu } from \"defu\";\nimport { lookupNodeModuleSubpath, parseNodeModulePath } from \"mlly\";\nimport { resolveModulePath } from \"exsolve\";\nimport { isDirectory, resolveNitroPath, writeFile } from \"../utils/fs.ts\";\nimport { runtimeDir } from \"nitro/meta\";\nimport type { Nitro, NitroTypes } from \"nitro/types\";\nimport { dirname, isAbsolute, join, resolve } from \"pathe\";\nimport { relative } from \"pathe\";\nimport { resolveAlias } from \"pathe/utils\";\nimport type { TSConfig } from \"pkg-types\";\nimport type { JSValue } from \"untyped\";\nimport { generateTypes, resolveSchema } from \"untyped\";\nimport { toExports } from \"unimport\";\n\nexport async function writeTypes(nitro: Nitro) {\n  const types: NitroTypes = {\n    routes: {},\n  };\n\n  const generatedTypesDir = resolve(\n    nitro.options.rootDir,\n    nitro.options.typescript.generatedTypesDir || \"node_modules/.nitro/types\"\n  );\n\n  const middleware = [...nitro.scannedHandlers, ...nitro.options.handlers];\n\n  for (const mw of middleware) {\n    if (typeof mw.handler !== \"string\" || !mw.route) {\n      continue;\n    }\n    const relativePath = relative(\n      generatedTypesDir,\n      resolveNitroPath(mw.handler, nitro.options)\n    ).replace(/\\.(js|mjs|cjs|ts|mts|cts|tsx|jsx)$/, \"\");\n\n    const method = mw.method || \"default\";\n\n    types.routes[mw.route] ??= {};\n    types.routes[mw.route][method] ??= [];\n    types.routes[mw.route][method]!.push(\n      `Simplify<Serialize<Awaited<ReturnType<typeof import('${relativePath}').default>>>>`\n    );\n  }\n\n  let autoImportedTypes: string[] = [];\n  let autoImportExports = \"\";\n\n  if (nitro.unimport) {\n    await nitro.unimport.init();\n\n    // TODO: fully resolve utils exported from `#imports`\n\n    const allImports = await nitro.unimport.getImports();\n\n    autoImportExports = toExports(allImports).replace(\n      /#internal\\/nitro/g,\n      relative(generatedTypesDir, runtimeDir)\n    );\n\n    const resolvedImportPathMap = new Map<string, string>();\n\n    for (const i of allImports) {\n      const from = i.typeFrom || i.from;\n      if (resolvedImportPathMap.has(from)) {\n        continue;\n      }\n      let path = resolveAlias(from, nitro.options.alias);\n      if (!isAbsolute(path)) {\n        const resolvedPath = resolveModulePath(from, {\n          try: true,\n          from: nitro.options.rootDir,\n          conditions: [\"type\", \"node\", \"import\"],\n          suffixes: [\"\", \"/index\"],\n          extensions: [\".mjs\", \".cjs\", \".js\", \".mts\", \".cts\", \".ts\"],\n        });\n        if (resolvedPath) {\n          const { dir, name } = parseNodeModulePath(resolvedPath);\n          if (!dir || !name) {\n            path = resolvedPath;\n          } else {\n            const subpath = await lookupNodeModuleSubpath(resolvedPath);\n            path = join(dir, name, subpath || \"\");\n          }\n        }\n      }\n      if (existsSync(path) && !(await isDirectory(path))) {\n        path = path.replace(/\\.[a-z]+$/, \"\");\n      }\n      if (isAbsolute(path)) {\n        path = relative(generatedTypesDir, path);\n      }\n      resolvedImportPathMap.set(from, path);\n    }\n\n    autoImportedTypes = [\n      nitro.options.imports && nitro.options.imports.autoImport !== false\n        ? (\n            await nitro.unimport.generateTypeDeclarations({\n              exportHelper: false,\n              resolvePath: (i) => {\n                const from = i.typeFrom || i.from;\n                return resolvedImportPathMap.get(from) ?? from;\n              },\n            })\n          ).trim()\n        : \"\",\n    ];\n  }\n\n  const generateRoutes = () => [\n    \"// Generated by nitro\",\n    'import type { Serialize, Simplify } from \"nitro/types\";',\n    'declare module \"nitro/types\" {',\n    \"  type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T\",\n    \"  interface InternalApi {\",\n    ...Object.entries(types.routes).map(([path, methods]) =>\n      [\n        `    '${path}': {`,\n        ...Object.entries(methods).map(\n          ([method, types]) => `      '${method}': ${types.join(\" | \")}`\n        ),\n        \"    }\",\n      ].join(\"\\n\")\n    ),\n    \"  }\",\n    \"}\",\n    // Makes this a module for augmentation purposes\n    \"export {}\",\n  ];\n\n  const config = [\n    \"// Generated by nitro\",\n    /* ts */ `declare module \"nitro/types\" {`,\n    nitro.options.typescript.generateRuntimeConfigTypes\n      ? generateTypes(\n          await resolveSchema(\n            Object.fromEntries(\n              Object.entries(nitro.options.runtimeConfig).filter(\n                ([key]) => ![\"app\", \"nitro\"].includes(key)\n              )\n            ) as Record<string, JSValue>\n          ),\n          {\n            interfaceName: \"NitroRuntimeConfig\",\n            addExport: false,\n            addDefaults: false,\n            allowExtraKeys: false,\n            indentation: 2,\n          }\n        )\n      : \"\",\n    `}`,\n    // Makes this a module for augmentation purposes\n    \"export {}\",\n  ];\n\n  const declarations = [\n    // local nitro augmentations\n    '/// <reference path=\"./nitro-routes.d.ts\" />',\n    '/// <reference path=\"./nitro-config.d.ts\" />',\n    // global server auto-imports\n    '/// <reference path=\"./nitro-imports.d.ts\" />',\n  ];\n\n  const buildFiles: { path: string; contents: string | (() => string) }[] = [];\n\n  buildFiles.push({\n    path: join(generatedTypesDir, \"nitro-routes.d.ts\"),\n    contents: () => generateRoutes().join(\"\\n\"),\n  });\n\n  buildFiles.push({\n    path: join(generatedTypesDir, \"nitro-config.d.ts\"),\n    contents: config.join(\"\\n\"),\n  });\n\n  buildFiles.push({\n    path: join(generatedTypesDir, \"nitro-imports.d.ts\"),\n    contents: [...autoImportedTypes, autoImportExports || \"export {}\"].join(\"\\n\"),\n  });\n\n  buildFiles.push({\n    path: join(generatedTypesDir, \"nitro.d.ts\"),\n    contents: declarations.join(\"\\n\"),\n  });\n\n  if (nitro.options.typescript.generateTsConfig) {\n    const tsConfigPath = resolve(\n      generatedTypesDir,\n      nitro.options.typescript.tsconfigPath || \"tsconfig.json\"\n    );\n    const tsconfigDir = dirname(tsConfigPath);\n    const tsConfig: TSConfig = defu(nitro.options.typescript.tsConfig, {\n      compilerOptions: {\n        /* Base options: */\n        esModuleInterop: true,\n        allowSyntheticDefaultImports: true,\n        skipLibCheck: true,\n        target: \"ESNext\",\n        allowJs: true,\n        resolveJsonModule: true,\n        moduleDetection: \"force\",\n        isolatedModules: true,\n        verbatimModuleSyntax: true,\n        allowImportingTsExtensions: true,\n        /* Strictness */\n        strict: nitro.options.typescript.strict,\n        noUncheckedIndexedAccess: true,\n        noImplicitOverride: true,\n        forceConsistentCasingInFileNames: true,\n        /* If NOT transpiling with TypeScript: */\n        module: \"Preserve\",\n        jsx: \"preserve\",\n        jsxFactory: \"h\",\n        jsxFragmentFactory: \"Fragment\",\n        paths: {\n          \"#imports\": [relativeWithDot(tsconfigDir, join(generatedTypesDir, \"nitro-imports\"))],\n        },\n      },\n      include: [\n        relativeWithDot(tsconfigDir, join(generatedTypesDir, \"nitro.d.ts\")).replace(\n          /^(?=[^.])/,\n          \"./\"\n        ),\n        join(relativeWithDot(tsconfigDir, nitro.options.rootDir), \"**/*\"),\n        ...(!nitro.options.serverDir || nitro.options.serverDir === nitro.options.rootDir\n          ? []\n          : [join(relativeWithDot(tsconfigDir, nitro.options.serverDir), \"**/*\")]),\n      ],\n    });\n\n    for (const alias in tsConfig.compilerOptions!.paths) {\n      const paths = await Promise.all(\n        tsConfig.compilerOptions!.paths[alias].map(async (path: string) => {\n          if (!isAbsolute(path)) {\n            return path;\n          }\n          const stats = await fsp.stat(path).catch(() => null /* file does not exist */);\n          return relativeWithDot(\n            tsconfigDir,\n            stats?.isFile() ? path.replace(/(?<=\\w)\\.\\w+$/g, \"\") /* remove extension */ : path\n          );\n        })\n      );\n      tsConfig.compilerOptions!.paths[alias] = [...new Set(paths)];\n    }\n\n    tsConfig.include = [\n      ...new Set(\n        tsConfig.include!.map((p) => (isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p))\n      ),\n    ];\n    if (tsConfig.exclude) {\n      tsConfig.exclude = [\n        ...new Set(\n          tsConfig.exclude!.map((p) => (isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p))\n        ),\n      ];\n    }\n\n    types.tsConfig = tsConfig;\n\n    buildFiles.push({\n      path: tsConfigPath,\n      contents: () => JSON.stringify(tsConfig, null, 2),\n    });\n  }\n\n  await nitro.hooks.callHook(\"types:extend\", types);\n\n  await Promise.all(\n    buildFiles.map(async (file) => {\n      await writeFile(\n        resolve(generatedTypesDir, file.path),\n        typeof file.contents === \"string\" ? file.contents : file.contents()\n      );\n    })\n  );\n}\n\nconst RELATIVE_RE = /^\\.{1,2}\\//;\n\nexport function relativeWithDot(from: string, to: string) {\n  const rel = relative(from, to);\n  return RELATIVE_RE.test(rel) ? rel : \"./\" + rel;\n}\n"
  },
  {
    "path": "src/build/virtual/_all.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nimport database from \"./database.ts\";\nimport errorHandler from \"./error-handler.ts\";\nimport featureFlags from \"./feature-flags.ts\";\nimport plugins from \"./plugins.ts\";\nimport polyfills from \"./polyfills.ts\";\nimport publicAssets from \"./public-assets.ts\";\nimport rendererTemplate from \"./renderer-template.ts\";\nimport routingMeta from \"./routing-meta.ts\";\nimport routing from \"./routing.ts\";\nimport runtimeConfig from \"./runtime-config.ts\";\nimport serverAssets from \"./server-assets.ts\";\nimport storage from \"./storage.ts\";\nimport tasks from \"./tasks.ts\";\n\ntype VirtualTemplate = {\n  id: string;\n  template: string | (() => string | Promise<string>);\n};\n\nexport function virtualTemplates(nitro: Nitro, _polyfills: string[]): VirtualTemplate[] {\n  const nitroTemplates = [\n    database,\n    errorHandler,\n    featureFlags,\n    plugins,\n    polyfills,\n    publicAssets,\n    rendererTemplate,\n    routingMeta,\n    routing,\n    runtimeConfig,\n    serverAssets,\n    storage,\n    tasks,\n  ].flatMap((t) => t(nitro, _polyfills));\n\n  const customTemplates = Object.entries(nitro.options.virtual).map(([id, template]) => ({\n    id,\n    template,\n  }));\n\n  return [...nitroTemplates, ...customTemplates];\n}\n"
  },
  {
    "path": "src/build/virtual/database.ts",
    "content": "import { connectors } from \"db0\";\nimport type { Nitro } from \"nitro/types\";\nimport { camelCase } from \"scule\";\n\nexport default function database(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/database\",\n    template: () => {\n      if (!nitro.options.experimental.database) {\n        return /* js */ `export const connectionConfigs = {};`;\n      }\n\n      const dbConfigs = (nitro.options.dev && nitro.options.devDatabase) || nitro.options.database;\n\n      const connectorsNames = [\n        ...new Set(Object.values(dbConfigs || {}).map((config) => config?.connector)),\n      ].filter(Boolean);\n\n      for (const name of connectorsNames) {\n        if (!connectors[name]) {\n          throw new Error(`Database connector \"${name}\" is invalid.`);\n        }\n      }\n\n      return /* js */ `\n${connectorsNames\n  .map((name) => /* js */ `import ${camelCase(name)}Connector from \"${connectors[name]}\";`)\n  .join(\"\\n\")}\n\nexport const connectionConfigs = {\n  ${Object.entries(dbConfigs || {})\n    .filter(([, config]) => !!config?.connector)\n    .map(\n      ([name, { connector, options }]) => /* js */ `${name}: {\n          connector: ${camelCase(connector)}Connector,\n          options: ${JSON.stringify(options)}\n        }`\n    )\n    .join(\",\\n\")}\n};\n        `;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/error-handler.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { runtimeDir } from \"nitro/meta\";\nimport { join } from \"pathe\";\n\nexport default function errorHandler(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/error-handler\",\n    template: () => {\n      const errorHandlers = Array.isArray(nitro.options.errorHandler)\n        ? nitro.options.errorHandler\n        : [nitro.options.errorHandler];\n\n      const builtinHandler = join(\n        runtimeDir,\n        `internal/error/${nitro.options.dev ? \"dev\" : \"prod\"}`\n      );\n\n      return /* js */ `\n${errorHandlers.map((h, i) => `import errorHandler$${i} from \"${h}\";`).join(\"\\n\")}\n\nconst errorHandlers = [${errorHandlers.map((_, i) => `errorHandler$${i}`).join(\", \")}];\n\nimport { defaultHandler } from \"${builtinHandler}\";\n\nexport default async function(error, event) {\n  for (const handler of errorHandlers) {\n    try {\n      const response = await handler(error, event, { defaultHandler });\n      if (response) {\n        return response;\n      }\n    } catch(error) {\n      // Handler itself thrown, log and continue\n      console.error(error);\n    }\n  }\n  // H3 will handle fallback\n}\n`;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/feature-flags.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nexport default function featureFlags(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/feature-flags\",\n    template: () => {\n      const featureFlags: Record<string, boolean> = {\n        // Routing\n        hasRoutes: nitro.routing.routes.hasRoutes(),\n        hasRouteRules: nitro.routing.routeRules.hasRoutes(),\n        hasRoutedMiddleware: nitro.routing.routedMiddleware.hasRoutes(),\n        hasGlobalMiddleware: nitro.routing.globalMiddleware.length > 0,\n        // Plugins\n        hasPlugins: nitro.options.plugins.length > 0,\n        hasHooks: nitro.options.features?.runtimeHooks ?? nitro.options.plugins.length > 0,\n      };\n      return /* js */ Object.entries(featureFlags)\n        .map(([key, value]) => /* js */ `export const ${key} = ${Boolean(value)};`)\n        .join(\"\\n\");\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/plugins.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { hash } from \"ohash\";\n\nexport default function plugins(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/plugins\",\n    template: () => {\n      const nitroPlugins = [...new Set(nitro.options.plugins)];\n\n      return /* js */ `\n  ${nitroPlugins\n    .map((plugin) => /* js */ `import _${hash(plugin).replace(/-/g, \"\")} from \"${plugin}\";`)\n    .join(\"\\n\")}\n\n  export const plugins = [\n    ${nitroPlugins.map((plugin) => `_${hash(plugin).replace(/-/g, \"\")}`).join(\",\\n\")}\n  ]\n      `;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/polyfills.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nexport default function polyfills(_nitro: Nitro, polyfills: string[]) {\n  return {\n    id: \"#nitro/virtual/polyfills\",\n    moduleSideEffects: true,\n    template: () => {\n      return (\n        polyfills.map((p) => /* js */ `import '${p}';`).join(\"\\n\") || /* js */ `/* No polyfills */`\n      );\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/public-assets.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport createEtag from \"etag\";\nimport { glob } from \"tinyglobby\";\nimport mime from \"mime\";\nimport type { Nitro } from \"nitro/types\";\nimport type { PublicAsset } from \"nitro/types\";\nimport { relative, resolve } from \"pathe\";\nimport { joinURL, withTrailingSlash } from \"ufo\";\nimport { runParallel } from \"../../utils/parallel.ts\";\n\nconst readAssetHandler: Record<\n  Exclude<Nitro[\"options\"][\"serveStatic\"] | \"true\" | \"false\", boolean>,\n  \"node\" | \"deno\" | \"null\" | \"inline\"\n> = {\n  true: \"node\",\n  node: \"node\",\n  false: \"null\",\n  deno: \"deno\",\n  inline: \"inline\",\n};\n\nexport default function publicAssets(nitro: Nitro) {\n  return [\n    // public-assets-data\n    {\n      id: \"#nitro/virtual/public-assets-data\",\n      template: async () => {\n        const assets: Record<string, PublicAsset> = {};\n        const files = await glob(\"**\", {\n          cwd: nitro.options.output.publicDir,\n          absolute: false,\n          dot: true,\n        });\n\n        const { errors } = await runParallel(\n          new Set(files),\n          async (id) => {\n            let mimeType = mime.getType(id.replace(/\\.(gz|br|zst)$/, \"\")) || \"text/plain\";\n            if (mimeType.startsWith(\"text\")) {\n              mimeType += \"; charset=utf-8\";\n            }\n            const fullPath = resolve(nitro.options.output.publicDir, id);\n            const [assetData, stat] = await Promise.all([\n              fsp.readFile(fullPath),\n              fsp.stat(fullPath),\n            ]);\n\n            const etag = createEtag(assetData);\n\n            const assetId = joinURL(nitro.options.baseURL, decodeURIComponent(id));\n\n            let encoding;\n            if (id.endsWith(\".gz\")) {\n              encoding = \"gzip\";\n            } else if (id.endsWith(\".br\")) {\n              encoding = \"br\";\n            } else if (id.endsWith(\".zst\")) {\n              encoding = \"zstd\";\n            }\n\n            assets[assetId] = {\n              type: nitro._prerenderMeta?.[assetId]?.contentType || mimeType,\n              encoding,\n              etag,\n              mtime: stat.mtime.toJSON(),\n              size: stat.size,\n              path: relative(nitro.options.output.serverDir, fullPath),\n              data:\n                nitro.options.serveStatic === \"inline\" ? assetData.toString(\"base64\") : undefined,\n            };\n          },\n          { concurrency: 25 }\n        );\n\n        if (errors.length > 0) {\n          throw new Error(`Failed to process public assets:\\n${errors.join(\"\\n\")}`, {\n            cause: errors,\n          });\n        }\n\n        return `export default ${JSON.stringify(assets, null, 2)};`;\n      },\n    },\n\n    // public-assets\n    {\n      id: \"#nitro/virtual/public-assets\",\n      template: () => {\n        const publicAssetBases = Object.fromEntries(\n          nitro.options.publicAssets\n            .filter((dir) => !dir.fallthrough && dir.baseURL !== \"/\")\n            .map((dir) => [\n              withTrailingSlash(joinURL(nitro.options.baseURL, dir.baseURL || \"/\")),\n              { maxAge: dir.maxAge },\n            ])\n        );\n\n        // prettier-ignore\n        type _serveStaticAsKey = Exclude<typeof nitro.options.serveStatic, boolean> | \"true\" | \"false\";\n        // prettier-ignore\n        const handlerName = readAssetHandler[nitro.options.serveStatic as _serveStaticAsKey] || \"null\";\n        const readAssetImport = `#nitro/virtual/public-assets-${handlerName}`;\n\n        return /* js */ `\nimport assets from '#nitro/virtual/public-assets-data'\nexport { readAsset } from \"${readAssetImport}\"\nexport const publicAssetBases = ${JSON.stringify(publicAssetBases)}\n\nexport function isPublicAssetURL(id = '') {\n  if (assets[id]) {\n    return true\n  }\n  for (const base in publicAssetBases) {\n    if (id.startsWith(base)) { return true }\n  }\n  return false\n}\n\nexport function getPublicAssetMeta(id = '') {\n  for (const base in publicAssetBases) {\n    if (id.startsWith(base)) { return publicAssetBases[base] }\n  }\n  return {}\n}\n\nexport function getAsset (id) {\n  return assets[id]\n}\n`;\n      },\n    },\n\n    // TODO: Handlers can be static templates!\n\n    // public-assets-node\n    {\n      id: \"#nitro/virtual/public-assets-node\",\n      template: () => {\n        return /* js */ `\nimport { promises as fsp } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport { resolve, dirname } from 'node:path'\nimport assets from '#nitro/virtual/public-assets-data'\nexport function readAsset (id) {\n  const serverDir = dirname(fileURLToPath(globalThis.__nitro_main__))\n  return fsp.readFile(resolve(serverDir, assets[id].path))\n}`;\n      },\n    },\n\n    // public-assets-deno\n    {\n      id: \"#nitro/virtual/public-assets-deno\",\n      template: () => {\n        return /* js */ `\nimport assets from '#nitro/virtual/public-assets-data'\nexport function readAsset (id) {\n  // https://deno.com/deploy/docs/serve-static-assets\n  const path = '.' + decodeURIComponent(new URL(\\`../public\\${id}\\`, 'file://').pathname)\n  return Deno.readFile(path);\n}`;\n      },\n    },\n\n    // public-assets-null\n    {\n      id: \"#nitro/virtual/public-assets-null\",\n      template: () => {\n        return /* js */ `\n    export function readAsset (id) {\n        return Promise.resolve(null);\n    }`;\n      },\n    },\n\n    // public-assets-inline\n    {\n      id: \"#nitro/virtual/public-assets-inline\",\n      template: () => {\n        return /* js */ `\n  import assets from '#nitro/virtual/public-assets-data'\n  export function readAsset (id) {\n    if (!assets[id]) { return undefined }\n    if (assets[id]._data) { return assets[id]._data }\n    if (!assets[id].data) { return assets[id].data }\n    assets[id]._data = Uint8Array.from(atob(assets[id].data), (c) => c.charCodeAt(0))\n    return assets[id]._data\n}`;\n      },\n    },\n  ];\n}\n"
  },
  {
    "path": "src/build/virtual/renderer-template.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { readFile } from \"node:fs/promises\";\nimport { hasTemplateSyntax, compileTemplateToString, RENDER_CONTEXT_KEYS } from \"rendu\";\n\nexport default function rendererTemplate(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/renderer-template\",\n    template: async () => {\n      const template = nitro.options.renderer?.template;\n      if (typeof template !== \"string\") {\n        // No template\n        return /* js */ `\n            export const rendererTemplate = () => '<!-- renderer.template is not set -->';\n            export const rendererTemplateFile = undefined;\n            export const isStaticTemplate = true;`;\n      }\n      if (nitro.options.dev) {\n        // Development\n        return /* js */ `\n            import { readFile } from 'node:fs/promises';\n            export const rendererTemplate = () => readFile(${JSON.stringify(template)}, \"utf8\");\n            export const rendererTemplateFile = ${JSON.stringify(template)};\n            export const isStaticTemplate = ${JSON.stringify(nitro.options.renderer?.static)};\n            `;\n      } else {\n        // Production\n        const html = await readFile(template, \"utf8\");\n        const isStatic = nitro.options.renderer?.static ?? !hasTemplateSyntax(html);\n        if (isStatic) {\n          return /* js */ `\n              import { HTTPResponse } from \"h3\";\n              export const rendererTemplate = () => new HTTPResponse(${JSON.stringify(html)}, { headers: { \"content-type\": \"text/html; charset=utf-8\" } });\n            `;\n        } else {\n          const template = compileTemplateToString(html, {\n            contextKeys: [...RENDER_CONTEXT_KEYS],\n          });\n          return /* js */ `\n            import { renderToResponse } from 'rendu'\n            import { serverFetch } from 'nitro/app'\n            const template = ${template};\n            export const rendererTemplate = (request) => renderToResponse(template, { request, context: { serverFetch } })\n            `;\n        }\n      }\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/routing-meta.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nexport default function routingMeta(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/routing-meta\",\n    template: () => {\n      const handlers = Object.values(nitro.routing.routes.routes).flatMap((h) => h.data);\n      const routeHandlers = uniqueBy(handlers, \"_importHash\");\n\n      return /* js */ `\n  ${routeHandlers\n    .map((h) => /* js */ `import ${h._importHash}Meta from \"${h.handler}?meta\";`)\n    .join(\"\\n\")}\nexport const handlersMeta = [\n  ${handlers\n    .map(\n      (h) =>\n        /* js */ `{ route: ${JSON.stringify(h.route)}, method: ${JSON.stringify(\n          h.method?.toLowerCase()\n        )}, meta: ${h._importHash}Meta }`\n    )\n    .join(\",\\n\")}\n  ];\n        `.trim();\n    },\n  };\n}\n\nfunction uniqueBy<T>(arr: T[], key: keyof T): T[] {\n  return [...new Map(arr.map((item) => [item[key], item])).values()];\n}\n"
  },
  {
    "path": "src/build/virtual/routing.ts",
    "content": "import type { Nitro, NitroEventHandler, NitroRouteRules } from \"nitro/types\";\n\nexport const RuntimeRouteRules = [\"headers\", \"redirect\", \"proxy\", \"cache\", \"basicAuth\"] as string[];\n\nexport default function routing(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/routing\",\n    template: () => {\n      const allHandlers = uniqueBy(\n        [\n          ...Object.values(nitro.routing.routes.routes).flatMap((h) => h.data),\n          ...Object.values(nitro.routing.routedMiddleware.routes).map((h) => h.data),\n          ...nitro.routing.globalMiddleware,\n        ],\n        \"_importHash\"\n      );\n\n      return /* js */ `\nimport * as __routeRules__ from \"#nitro/runtime/route-rules\";\nimport * as srvxNode from \"srvx/node\"\nimport * as h3 from \"h3\";\n\nexport const findRouteRules = ${nitro.routing.routeRules.compileToString({ serialize: serializeRouteRule, matchAll: true })}\n\nconst multiHandler = (...handlers) => {\n  const final = handlers.pop()\n  const middleware = handlers.filter(Boolean).map(h => h3.toMiddleware(h));\n  return (ev) => h3.callMiddleware(ev, middleware, final);\n}\n\n${allHandlers\n  .filter((h) => !h.lazy)\n  .map((h) => /* js */ `import ${h._importHash} from \"${h.handler}\";`)\n  .join(\"\\n\")}\n\n${allHandlers\n  .filter((h) => h.lazy)\n  .map(\n    (h) =>\n      /* js */ `const ${h._importHash} = h3.defineLazyEventHandler(() => import(\"${h.handler}\")${h.format === \"node\" ? \".then(m => srvxNode.toFetchHandler(m.default))\" : \"\"});`\n  )\n  .join(\"\\n\")}\n\nexport const findRoute = ${nitro.routing.routes.compileToString({ serialize: serializeHandler })}\n\nexport const findRoutedMiddleware = ${nitro.routing.routedMiddleware.compileToString({ serialize: serializeHandler, matchAll: true })};\n\nexport const globalMiddleware = [\n  ${nitro.routing.globalMiddleware.map((h) => (h.lazy ? h._importHash : `h3.toEventHandler(${h._importHash})`)).join(\",\")}\n].filter(Boolean);\n  `;\n    },\n  };\n}\n\nfunction uniqueBy<T>(arr: T[], key: keyof T): T[] {\n  return [...new Map(arr.map((item) => [item[key], item])).values()];\n}\n\n// --- Serializing ---\n\ntype MaybeArray<T> = T | T[];\n\nfunction serializeHandler(h: MaybeArray<NitroEventHandler & { _importHash: string }>): string {\n  const meta = Array.isArray(h) ? h[0] : h;\n\n  return `{${[\n    `route:${JSON.stringify(meta.route)}`,\n    meta.method && `method:${JSON.stringify(meta.method)}`,\n    meta.meta && `meta:${JSON.stringify(meta.meta)}`,\n    `handler:${\n      Array.isArray(h)\n        ? `multiHandler(${h.map((handler) => serializeHandlerFn(handler)).join(\",\")})`\n        : serializeHandlerFn(h)\n    }`,\n  ]\n    .filter(Boolean)\n    .join(\",\")}}`;\n}\n\nfunction serializeHandlerFn(h: NitroEventHandler & { _importHash: string }): string {\n  let code = h._importHash;\n  if (!h.lazy) {\n    if (h.format === \"node\") {\n      code = `srvxNode.toFetchHandler(${code})`;\n    }\n    code = `h3.toEventHandler(${code})`;\n  }\n  return code;\n}\n\nfunction serializeRouteRule(h: NitroRouteRules & { _route: string }): string {\n  return `[${Object.entries(h)\n    .filter(([name, options]) => options !== undefined && name[0] !== \"_\")\n    .map(([name, options]) => {\n      return `{${[\n        `name:${JSON.stringify(name)}`,\n        `route:${JSON.stringify(h._route)}`,\n        h._method && `method:${JSON.stringify(h._method)}`,\n        RuntimeRouteRules.includes(name) && `handler:__routeRules__.${name}`,\n        `options:${JSON.stringify(options)}`,\n      ]\n        .filter(Boolean)\n        .join(\",\")}}`;\n    })\n    .join(\",\")}]`;\n}\n"
  },
  {
    "path": "src/build/virtual/runtime-config.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nexport default function runtimeConfig(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/runtime-config\",\n    template: () => {\n      return /* js */ `export const runtimeConfig = ${JSON.stringify(\n        nitro.options.runtimeConfig || {}\n      )};`;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/server-assets.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport createEtag from \"etag\";\nimport { glob } from \"tinyglobby\";\nimport mime from \"mime\";\nimport type { Nitro } from \"nitro/types\";\nimport { resolve } from \"pathe\";\nimport { normalizeKey } from \"unstorage\";\n\ninterface ResolvedAsset {\n  fsPath: string;\n  meta: {\n    type?: string;\n    etag?: string;\n    mtime?: string;\n  };\n}\n\nexport default function serverAssets(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/server-assets\",\n    template: async () => {\n      if (nitro.options.dev || nitro.options.preset === \"nitro-prerender\") {\n        return /* js */ `\n          import { createStorage } from 'unstorage'\n          import fsDriver from 'unstorage/drivers/fs'\n          const serverAssets = ${JSON.stringify(nitro.options.serverAssets)}\n          export const assets = createStorage()\n          for (const asset of serverAssets) {\n            assets.mount(asset.baseName, fsDriver({ base: asset.dir, ignore: (asset?.ignore || []) }))\n          }`;\n      }\n\n      // Scan all assets\n      const assets: Record<string, ResolvedAsset> = {};\n      for (const asset of nitro.options.serverAssets) {\n        const files = await glob(asset.pattern || \"**/*\", {\n          cwd: asset.dir,\n          absolute: false,\n          ignore: asset.ignore,\n        });\n        for (const _id of files) {\n          const fsPath = resolve(asset.dir, _id);\n          const id = asset.baseName + \"/\" + _id;\n          assets[id] = { fsPath, meta: {} };\n          // @ts-ignore TODO: Use mime@2 types\n          let type = mime.getType(id) || \"text/plain\";\n          if (type.startsWith(\"text\")) {\n            type += \"; charset=utf-8\";\n          }\n          const etag = createEtag(await fsp.readFile(fsPath));\n          const mtime = await fsp.stat(fsPath).then((s) => s.mtime.toJSON());\n          assets[id].meta = { type, etag, mtime };\n        }\n      }\n      return /* js */ `\nconst _assets = {\\n${Object.entries(assets)\n        .map(\n          ([id, asset]) =>\n            `  [${JSON.stringify(normalizeKey(id))}]: {\\n    import: () => import(${JSON.stringify(\n              \"raw:\" + asset.fsPath\n            )}).then(r => r.default || r),\\n    meta: ${JSON.stringify(asset.meta)}\\n  }`\n        )\n        .join(\",\\n\")}\\n}\n\nconst normalizeKey = ${normalizeKey.toString()}\n\nexport const assets = {\n  getKeys() {\n    return Promise.resolve(Object.keys(_assets))\n  },\n  hasItem (id) {\n    id = normalizeKey(id)\n    return Promise.resolve(id in _assets)\n  },\n  getItem (id) {\n    id = normalizeKey(id)\n    return Promise.resolve(_assets[id] ? _assets[id].import() : null)\n  },\n  getMeta (id) {\n    id = normalizeKey(id)\n    return Promise.resolve(_assets[id] ? _assets[id].meta : {})\n  }\n}\n`;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/storage.ts",
    "content": "import { genImport, genSafeVariableName } from \"knitwork\";\nimport type { Nitro } from \"nitro/types\";\nimport { builtinDrivers } from \"unstorage\";\n\nexport default function storage(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/storage\",\n    template: () => {\n      const mounts: { path: string; driver: string; opts: object }[] = [];\n\n      const isDevOrPrerender = nitro.options.dev || nitro.options.preset === \"nitro-prerender\";\n      const storageMounts = isDevOrPrerender\n        ? { ...nitro.options.storage, ...nitro.options.devStorage }\n        : nitro.options.storage;\n\n      for (const path in storageMounts) {\n        const { driver: driverName, ...driverOpts } = storageMounts[path];\n        mounts.push({\n          path,\n          driver: builtinDrivers[driverName as keyof typeof builtinDrivers] || driverName,\n          opts: driverOpts,\n        });\n      }\n\n      const driverImports = [...new Set(mounts.map((m) => m.driver))];\n\n      return /* js */ `\nimport { createStorage } from 'unstorage'\nimport { assets } from '#nitro/virtual/server-assets'\n\n${driverImports.map((i) => genImport(i, genSafeVariableName(i))).join(\"\\n\")}\n\nexport function initStorage() {\n  const storage = createStorage({})\n  storage.mount('/assets', assets)\n  ${mounts\n    .map(\n      (m) =>\n        `storage.mount('${m.path}', ${genSafeVariableName(m.driver)}(${JSON.stringify(m.opts)}))`\n    )\n    .join(\"\\n\")}\n  return storage\n}\n`;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/virtual/tasks.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { normalize } from \"pathe\";\n\nexport default function tasks(nitro: Nitro) {\n  return {\n    id: \"#nitro/virtual/tasks\",\n    template: () => {\n      const _scheduledTasks = Object.entries(nitro.options.scheduledTasks || {})\n        .map(([cron, _tasks]) => {\n          const tasks = (Array.isArray(_tasks) ? _tasks : [_tasks]).filter((name) => {\n            if (!nitro.options.tasks[name]) {\n              nitro.logger.warn(`Scheduled task \\`${name}\\` is not defined!`);\n              return false;\n            }\n            return true;\n          });\n          return { cron, tasks };\n        })\n        .filter((e) => e.tasks.length > 0);\n      const scheduledTasks: false | { cron: string; tasks: string[] }[] =\n        _scheduledTasks.length > 0 ? _scheduledTasks : false;\n\n      return /* js */ `\nexport const scheduledTasks = ${JSON.stringify(scheduledTasks)};\n\nexport const tasks = {\n  ${Object.entries(nitro.options.tasks)\n    .map(\n      ([name, task]) =>\n        `\"${name}\": {\n          meta: {\n            description: ${JSON.stringify(task.description)},\n          },\n          resolve: ${\n            task.handler\n              ? /* js */ `() => import(\"${normalize(task.handler)}\").then(r => r.default || r)`\n              : \"undefined\"\n          },\n        }`\n    )\n    .join(\",\\n\")}\n};`;\n    },\n  };\n}\n"
  },
  {
    "path": "src/build/vite/build.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { isTest } from \"std-env\";\nimport { nitro as nitroPlugin } from \"nitro/vite\";\n\nexport async function viteBuild(nitro: Nitro) {\n  if (nitro.options.dev) {\n    throw new Error(\"Nitro dev CLI does not supports vite. Please use `vite dev` instead.\");\n  }\n  const { createBuilder } = await import((nitro.options as any).__vitePkg__ || \"vite\");\n  const pluginInstance = nitroPlugin({ _nitro: nitro });\n  (globalThis as any).__nitro_build__ = true;\n  const builder = await createBuilder({\n    base: nitro.options.rootDir,\n    plugins: [pluginInstance],\n    logLevel: isTest ? \"warn\" : undefined,\n  });\n  delete (globalThis as any).__nitro_build__;\n  await builder.buildApp();\n}\n"
  },
  {
    "path": "src/build/vite/bundler.ts",
    "content": "import { defu } from \"defu\";\nimport { baseBuildConfig, type BaseBuildConfig } from \"../config.ts\";\nimport { getChunkName, libChunkName, NODE_MODULES_RE } from \"../chunks.ts\";\nimport { baseBuildPlugins } from \"../plugins.ts\";\n\nimport type { RolldownConfig, RollupConfig } from \"nitro/types\";\nimport type { Plugin as RollupPlugin } from \"rollup\";\nimport type { NitroPluginContext } from \"./types.ts\";\n\nexport const getBundlerConfig = async (\n  ctx: NitroPluginContext\n): Promise<{\n  base: BaseBuildConfig;\n  rollupConfig?: RollupConfig;\n  rolldownConfig?: RolldownConfig;\n}> => {\n  const nitro = ctx.nitro!;\n  const base = baseBuildConfig(nitro);\n\n  const commonConfig = {\n    input: nitro.options.entry,\n    external: [...base.env.external],\n    plugins: [...(await baseBuildPlugins(nitro, base))].filter(Boolean) as RollupPlugin[],\n    treeshake: {\n      moduleSideEffects(id) {\n        return nitro.options.moduleSideEffects.some((p) => id.startsWith(p));\n      },\n    },\n    onwarn(warning, warn) {\n      if (!base.ignoreWarningCodes.has(warning.code || \"\")) {\n        warn(warning);\n      }\n    },\n    output: {\n      dir: nitro.options.output.serverDir,\n      format: \"esm\",\n      entryFileNames: \"index.mjs\",\n      chunkFileNames: (chunk: { name: string; moduleIds: string[] }) => getChunkName(chunk, nitro),\n      inlineDynamicImports: nitro.options.inlineDynamicImports,\n      sourcemapIgnoreList: (id) => id.includes(\"node_modules\"),\n    },\n  } satisfies RollupConfig & RolldownConfig;\n\n  if (ctx._isRolldown) {\n    // Rolldown\n    const rolldownConfig: RolldownConfig = defu(\n      {\n        transform: {\n          inject: base.env.inject as Record<string, string>,\n        },\n        output: {\n          codeSplitting: {\n            groups: [\n              {\n                test: NODE_MODULES_RE,\n                name: (id: string) => libChunkName(id),\n              },\n            ],\n          },\n        },\n      } satisfies RolldownConfig,\n      nitro.options.rolldownConfig,\n      nitro.options.rollupConfig as RolldownConfig, // Added for backward compatibility\n      commonConfig satisfies RolldownConfig\n    );\n\n    const outputConfig = rolldownConfig.output!;\n    if (outputConfig.inlineDynamicImports || outputConfig.format === (\"iife\" as string)) {\n      delete outputConfig.inlineDynamicImports;\n      outputConfig.codeSplitting = false;\n    }\n\n    return { base, rolldownConfig };\n  } else {\n    // Rollup\n    const inject = (\n      (await import(\"@rollup/plugin-inject\")) as unknown as typeof import(\"@rollup/plugin-inject\")\n    ).default;\n    const alias = (\n      (await import(\"@rollup/plugin-alias\")) as unknown as typeof import(\"@rollup/plugin-alias\")\n    ).default;\n\n    const rollupConfig: RollupConfig = defu(\n      {\n        plugins: [inject(base.env.inject), alias({ entries: base.aliases })],\n        output: {\n          sourcemapExcludeSources: true,\n          generatedCode: {\n            constBindings: true,\n          },\n          manualChunks(id: string) {\n            if (NODE_MODULES_RE.test(id)) {\n              return libChunkName(id);\n            }\n          },\n        },\n      } satisfies RollupConfig,\n      nitro.options.rolldownConfig as RollupConfig, // Added for backward compatibility\n      nitro.options.rollupConfig,\n      commonConfig\n    );\n\n    const outputConfig = rollupConfig.output!;\n    if (outputConfig.inlineDynamicImports || outputConfig.format === (\"iife\" as string)) {\n      delete outputConfig.manualChunks;\n    }\n\n    return { base, rollupConfig };\n  }\n};\n"
  },
  {
    "path": "src/build/vite/dev.ts",
    "content": "import type { NitroPluginContext } from \"./types.ts\";\nimport type { DevEnvironmentContext, ResolvedConfig, ViteDevServer } from \"vite\";\nimport type { FetchFunctionOptions, FetchResult } from \"vite/module-runner\";\nimport type { RunnerRPCHooks } from \"env-runner\";\n\nimport { IncomingMessage, ServerResponse } from \"node:http\";\nimport { NodeRequest, sendNodeResponse } from \"srvx/node\";\nimport { DevEnvironment } from \"vite\";\nimport { createViteHotChannel } from \"env-runner/vite\";\nimport { watch as chokidarWatch } from \"chokidar\";\nimport { watch as fsWatch } from \"node:fs\";\nimport { join } from \"pathe\";\nimport { debounce } from \"perfect-debounce\";\nimport { scanHandlers } from \"../../scan.ts\";\nimport { getEnvRunner } from \"./env.ts\";\n\n// https://vite.dev/guide/api-environment-runtimes.html#modulerunner\n\n// ---- Types ----\n\nexport type FetchHandler = (req: Request) => Promise<Response>;\n\nexport interface DevServer extends RunnerRPCHooks {\n  fetch: FetchHandler;\n  init?: () => void | Promise<void>;\n}\n\n// ---- Fetchable Dev Environment ----\n\nexport function createFetchableDevEnvironment(\n  name: string,\n  config: ResolvedConfig,\n  devServer: DevServer,\n  entry: string,\n  opts?: { preventExternalize?: boolean }\n): FetchableDevEnvironment {\n  const transport = createViteHotChannel(devServer, name);\n  const context: DevEnvironmentContext = { hot: true, transport };\n  return new FetchableDevEnvironment(name, config, context, devServer, entry, opts);\n}\n\nexport class FetchableDevEnvironment extends DevEnvironment {\n  devServer: DevServer;\n\n  #entry: string;\n  #preventExternalize: boolean;\n\n  constructor(\n    name: string,\n    config: ResolvedConfig,\n    context: DevEnvironmentContext,\n    devServer: DevServer,\n    entry: string,\n    opts?: { preventExternalize?: boolean }\n  ) {\n    super(name, config, context);\n    this.devServer = devServer;\n    this.#entry = entry;\n    this.#preventExternalize = opts?.preventExternalize ?? false;\n  }\n\n  override async fetchModule(\n    id: string,\n    importer?: string,\n    options?: FetchFunctionOptions\n  ): Promise<FetchResult> {\n    // workerd cannot handle CJS/Node modules loaded via import().\n    // Bare imports (like \"vue\") are normally externalized by Vite's fetchModule,\n    // resolved using mainFields: [\"main\"] which often picks CJS entries.\n    // We intercept bare imports, resolve them through the environment's plugin\n    // pipeline (which respects resolve.conditions and picks ESM), then route\n    // the resolved path through transformRequest for proper SSR processing.\n    if (\n      this.#preventExternalize &&\n      !id.startsWith(\"file://\") &&\n      importer &&\n      id[0] !== \".\" &&\n      id[0] !== \"/\"\n    ) {\n      const resolved = await this.pluginContainer.resolveId(id, importer);\n      if (resolved && !resolved.external) {\n        return super.fetchModule(resolved.id, importer, options);\n      }\n    }\n    return super.fetchModule(id, importer, options);\n  }\n\n  async dispatchFetch(request: Request): Promise<Response> {\n    return this.devServer.fetch(request);\n  }\n\n  override async init(...args: any[]): Promise<void> {\n    await this.devServer.init?.();\n    await super.init(...args);\n    this.devServer.sendMessage({\n      type: \"custom\",\n      event: \"nitro:vite-env\",\n      data: { name: this.name, entry: this.#entry },\n    });\n  }\n}\n\n// ---- Vite Dev Server Integration ----\n\nexport async function configureViteDevServer(ctx: NitroPluginContext, server: ViteDevServer) {\n  const nitro = ctx.nitro!;\n  const nitroEnv = server.environments.nitro as FetchableDevEnvironment;\n\n  // Restart with nitro.config changes\n  const nitroConfigFile = nitro.options._c12.configFile;\n  if (nitroConfigFile) {\n    server.config.configFileDependencies.push(nitroConfigFile);\n  }\n\n  // Websocket\n  if (nitro.options.features.websocket ?? nitro.options.experimental.websocket) {\n    server.httpServer!.on(\"upgrade\", (req, socket, head) => {\n      const protocol = req.headers[\"sec-websocket-protocol\"];\n      if (protocol?.startsWith(\"vite-\")) {\n        // Vite HMR WebSocket connection\n        return;\n      }\n      getEnvRunner(ctx).upgrade?.({ node: { req, socket, head } });\n    });\n  }\n\n  // Rebuild on scan dir changes\n  const reload = debounce(async () => {\n    await scanHandlers(nitro);\n    nitro.routing.sync();\n    nitroEnv.moduleGraph.invalidateAll();\n    nitroEnv.hot.send({ type: \"full-reload\" });\n  });\n\n  const scanDirs = nitro.options.scanDirs.flatMap((dir) => [\n    join(dir, nitro.options.apiDir || \"api\"),\n    join(dir, nitro.options.routesDir || \"routes\"),\n    join(dir, \"middleware\"),\n    join(dir, \"plugins\"),\n    join(dir, \"modules\"),\n  ]);\n\n  const watchReloadEvents = new Set([\"add\", \"addDir\", \"unlink\", \"unlinkDir\"]);\n  const scanDirsWatcher = chokidarWatch(scanDirs, {\n    ignoreInitial: true,\n  }).on(\"all\", (event, path, stat) => {\n    if (watchReloadEvents.has(event)) {\n      reload();\n    }\n  });\n\n  const rootDirWatcher = fsWatch(\n    nitro.options.rootDir,\n    { persistent: false },\n    (_event, filename) => {\n      if (filename && /^server\\.[mc]?[jt]sx?$/.test(filename)) {\n        reload();\n      }\n    }\n  );\n  nitro.hooks.hook(\"close\", () => {\n    scanDirsWatcher.close();\n    rootDirWatcher.close();\n  });\n\n  // Worker => Host RPC\n  nitroEnv.devServer.onMessage(async (message: any) => {\n    if (message?.__rpc === \"transformHTML\") {\n      try {\n        const html = (await server.transformIndexHtml(\"/\", message.data)).replace(\n          \"<!--ssr-outlet-->\",\n          `{{{ globalThis.__nitro_vite_envs__?.[\"ssr\"]?.fetch($REQUEST) || \"\" }}}`\n        );\n        nitroEnv.devServer.sendMessage({ __rpc_id: message.__rpc_id, data: html });\n      } catch (error) {\n        nitroEnv.devServer.sendMessage({\n          __rpc_id: message.__rpc_id,\n          error: error instanceof Error ? error.message : String(error),\n        });\n      }\n    }\n  });\n\n  const nitroDevMiddleware = async (\n    nodeReq: IncomingMessage & { _nitroHandled?: boolean },\n    nodeRes: ServerResponse,\n    next: (error?: unknown) => void\n  ) => {\n    // Skip for vite internal requests or if already handled\n    if (\n      !nodeReq.url ||\n      /^\\/@(?:vite|fs|id)\\//.test(nodeReq.url) ||\n      nodeReq._nitroHandled ||\n      server.middlewares.stack\n        .map((mw) => mw.route)\n        .some((base) => base && nodeReq.url!.startsWith(base))\n    ) {\n      return next();\n    }\n    nodeReq._nitroHandled = true;\n    try {\n      // Create web API compat request\n      const req = new NodeRequest({ req: nodeReq, res: nodeRes });\n\n      // Try dev app\n      const devAppRes = await ctx.devApp!.fetch(req);\n      if (nodeRes.writableEnded || nodeRes.headersSent) {\n        return;\n      }\n      if (devAppRes.status !== 404) {\n        return await sendNodeResponse(nodeRes, devAppRes);\n      }\n\n      // Dispatch the request to the nitro environment\n      const envRes = await nitroEnv.dispatchFetch(req);\n      if (nodeRes.writableEnded || nodeRes.headersSent) {\n        return;\n      }\n      return await sendNodeResponse(nodeRes, envRes);\n    } catch (error) {\n      return next(error);\n    }\n  };\n\n  // Handle server routes first to avoid conflicts with static assets served by Vite from the root\n  // https://github.com/vitejs/vite/pull/20866\n  server.middlewares.use(function nitroDevMiddlewarePre(req, res, next) {\n    const fetchDest = req.headers[\"sec-fetch-dest\"];\n    res.setHeader(\"vary\", \"sec-fetch-dest\");\n    if (\n      // Originating from browser tab or no fetch dest (curl, fetch, etc) and (not script, style, image, etc)\n      (!fetchDest || /^(document|iframe|frame|empty)$/.test(fetchDest)) &&\n      // No file extension (not /src/index.ts)\n      !req.url!.match(/\\.([a-z0-9]+)(?:[?#]|$)/i)?.[1] &&\n      // Special prefixes (/__vue-router/auto-routes, /@vite-plugin-layouts/, etc)\n      !/^\\/(?:__|@)/.test(req.url!)\n    ) {\n      nitroDevMiddleware(req, res, next);\n    } else {\n      next();\n    }\n  });\n\n  return () => {\n    server.middlewares.use(nitroDevMiddleware);\n  };\n}\n"
  },
  {
    "path": "src/build/vite/env.ts",
    "content": "import type { EnvironmentOptions, RollupCommonJSOptions } from \"vite\";\nimport type { NitroPluginContext, ServiceConfig } from \"./types.ts\";\n\nimport type { RunnerName } from \"env-runner\";\nimport { RunnerManager, loadRunner } from \"env-runner\";\nimport { join, resolve } from \"node:path\";\nimport { runtimeDependencies, runtimeDir } from \"nitro/meta\";\nimport { resolveModulePath } from \"exsolve\";\nimport { createFetchableDevEnvironment } from \"./dev.ts\";\nimport { isAbsolute } from \"pathe\";\n\nexport function createNitroEnvironment(ctx: NitroPluginContext): EnvironmentOptions {\n  const isWorkerdRunner = _isWorkerdRunner(ctx);\n  return {\n    consumer: \"server\",\n    build: {\n      rollupOptions: ctx.bundlerConfig!.rollupConfig as any,\n      rolldownOptions: ctx.bundlerConfig!.rolldownConfig,\n      minify: ctx.nitro!.options.minify,\n      emptyOutDir: false,\n      sourcemap: ctx.nitro!.options.sourcemap,\n      commonjsOptions: ctx.nitro!.options.commonJS as RollupCommonJSOptions,\n      copyPublicDir: false,\n    },\n    resolve: {\n      noExternal: ctx.nitro!.options.dev\n        ? isWorkerdRunner\n          ? true\n          : [\n              /^nitro$/, // i have absolutely no idea why and how it fixes issues!\n              new RegExp(`^(${runtimeDependencies.join(\"|\")})$`), // virtual resolutions in vite skip plugin hooks\n              ...ctx.bundlerConfig!.base.noExternal,\n            ]\n        : true, // production build is standalone\n      // workerd cannot handle CJS modules, so we must avoid the \"node\" export\n      // condition which often resolves to CJS entries.\n      conditions: isWorkerdRunner\n        ? [\"workerd\", \"worker\", ...ctx.nitro!.options.exportConditions!.filter((c) => c !== \"node\")]\n        : ctx.nitro!.options.exportConditions,\n      externalConditions: ctx.nitro!.options.exportConditions?.filter(\n        (c) => !/browser|wasm|module/.test(c)\n      ),\n    },\n    define: {\n      // Workaround for tanstack-start (devtools)\n      \"process.env.NODE_ENV\": JSON.stringify(ctx.nitro!.options.dev ? \"development\" : \"production\"),\n    },\n    dev: {\n      createEnvironment: (envName, envConfig) => {\n        const entry = resolve(runtimeDir, \"internal/vite/dev-entry.mjs\");\n        const env = createFetchableDevEnvironment(envName, envConfig, getEnvRunner(ctx), entry, {\n          preventExternalize: isWorkerdRunner,\n        });\n        ctx._transformRequest = (id) => env.transformRequest(id);\n        (ctx._viteEnvs ??= new Map()).set(envName, entry);\n        return env;\n      },\n    },\n  };\n}\n\nexport function createServiceEnvironment(\n  ctx: NitroPluginContext,\n  name: string,\n  serviceConfig: ServiceConfig\n): EnvironmentOptions {\n  const isWorkerdRunner = _isWorkerdRunner(ctx);\n  return {\n    consumer: \"server\",\n    build: {\n      rollupOptions: { input: { index: serviceConfig.entry } },\n      minify: ctx.nitro!.options.minify,\n      sourcemap: ctx.nitro!.options.sourcemap,\n      outDir: join(ctx.nitro!.options.buildDir, \"vite/services\", name),\n      emptyOutDir: true,\n      copyPublicDir: false,\n    },\n    resolve: {\n      ...(isWorkerdRunner ? { noExternal: true } : {}),\n      conditions: isWorkerdRunner\n        ? [\"workerd\", \"worker\", ...ctx.nitro!.options.exportConditions!.filter((c) => c !== \"node\")]\n        : ctx.nitro!.options.exportConditions,\n      externalConditions: ctx.nitro!.options.exportConditions?.filter(\n        (c) => !/browser|wasm|module/.test(c)\n      ),\n    },\n    dev: {\n      createEnvironment: (envName, envConfig) => {\n        const entry = tryResolve(serviceConfig.entry);\n        (ctx._viteEnvs ??= new Map()).set(envName, entry);\n        return createFetchableDevEnvironment(envName, envConfig, getEnvRunner(ctx), entry, {\n          preventExternalize: isWorkerdRunner,\n        });\n      },\n    },\n  };\n}\n\nexport function createServiceEnvironments(\n  ctx: NitroPluginContext\n): Record<string, EnvironmentOptions> {\n  return Object.fromEntries(\n    Object.entries(ctx.services).map(([name, config]) => [\n      name,\n      createServiceEnvironment(ctx, name, config),\n    ])\n  );\n}\n\nexport async function initEnvRunner(ctx: NitroPluginContext) {\n  if (ctx._envRunner) {\n    return ctx._envRunner;\n  }\n  if (!ctx._initPromise) {\n    ctx._initPromise = (async () => {\n      const manager = new RunnerManager();\n      let _retries = 0;\n      manager.onClose((_runner, cause) => {\n        if (_retries++ < 3) {\n          ctx.nitro!.logger.info(\"Restarting env runner...\", cause ? `Cause: ${cause}` : \"\");\n          _loadRunner(ctx, manager);\n        } else {\n          ctx.nitro!.logger.error(\n            \"Env runner failed after 3 retries.\",\n            cause ? `Last cause: ${cause}` : \"\"\n          );\n        }\n      });\n      manager.onReady(() => {\n        _retries = 0;\n        if (ctx._viteEnvs) {\n          for (const [name, entry] of ctx._viteEnvs) {\n            manager.sendMessage({\n              type: \"custom\",\n              event: \"nitro:vite-env\",\n              data: { name, entry },\n            });\n          }\n        }\n      });\n      await _loadRunner(ctx, manager);\n      ctx._envRunner = manager;\n      return manager;\n    })();\n  }\n  return await ctx._initPromise;\n}\n\nexport function getEnvRunner(ctx: NitroPluginContext) {\n  if (!ctx._envRunner) {\n    throw new Error(\"Env runner not initialized. Call initEnvRunner() first.\");\n  }\n  return ctx._envRunner;\n}\n\nexport async function reloadEnvRunner(ctx: NitroPluginContext) {\n  const manager = ctx._envRunner;\n  if (!manager) {\n    return initEnvRunner(ctx);\n  }\n  await _loadRunner(ctx, manager);\n  return manager;\n}\n\nasync function _loadRunner(ctx: NitroPluginContext, manager: RunnerManager) {\n  const runnerName = (ctx.nitro!.options.devServer.runner ||\n    process.env.NITRO_DEV_RUNNER ||\n    \"node-worker\") as RunnerName;\n  const entry = resolve(runtimeDir, \"internal/vite/dev-worker.mjs\");\n  let runner;\n  if (runnerName === \"miniflare\") {\n    const { MiniflareEnvRunner } = await import(\"env-runner/runners/miniflare\");\n    runner = new MiniflareEnvRunner({\n      name: \"nitro-vite\",\n      data: { entry },\n    });\n  } else {\n    runner = await loadRunner(runnerName, {\n      name: \"nitro-vite\",\n      data: { entry },\n    });\n  }\n  await manager.reload(runner);\n}\n\n// workerd-based runners (miniflare) cannot handle CJS externals via import(),\n// so all dependencies must be processed through Vite's transform pipeline.\nfunction _isWorkerdRunner(ctx: NitroPluginContext): boolean {\n  const runnerName =\n    ctx.nitro!.options.devServer.runner || process.env.NITRO_DEV_RUNNER || \"node-worker\";\n  return runnerName === \"miniflare\";\n}\n\nfunction tryResolve(id: string) {\n  if (/^[~#/\\0]/.test(id) || isAbsolute(id)) {\n    return id;\n  }\n  const resolved = resolveModulePath(id, {\n    suffixes: [\"\", \"/index\"],\n    extensions: [\"\", \".ts\", \".mjs\", \".cjs\", \".js\", \".mts\", \".cts\"],\n    try: true,\n  });\n  return resolved || id;\n}\n"
  },
  {
    "path": "src/build/vite/plugin.ts",
    "content": "import type {\n  ConfigEnv,\n  EnvironmentModuleNode,\n  EnvironmentOptions,\n  PluginOption,\n  UserConfig,\n  Plugin as VitePlugin,\n} from \"vite\";\nimport type { InputOption } from \"rollup\";\nimport type { NitroPluginConfig, NitroPluginContext } from \"./types.ts\";\nimport { resolve, join } from \"pathe\";\nimport { createNitro, prepare } from \"../../builder.ts\";\nimport { getBundlerConfig } from \"./bundler.ts\";\nimport { buildEnvironments, prodSetup } from \"./prod.ts\";\nimport {\n  initEnvRunner,\n  getEnvRunner,\n  createNitroEnvironment,\n  createServiceEnvironments,\n  createServiceEnvironment,\n} from \"./env.ts\";\nimport { configureViteDevServer } from \"./dev.ts\";\nimport { runtimeDir } from \"nitro/meta\";\nimport { resolveModulePath } from \"exsolve\";\nimport { defu } from \"defu\";\nimport { prettyPath } from \"../../utils/fs.ts\";\nimport { NitroDevApp } from \"../../dev/app.ts\";\nimport { nitroPreviewPlugin } from \"./preview.ts\";\nimport assetsPlugin from \"@hiogawa/vite-plugin-fullstack/assets\";\nimport type { NitroConfig } from \"nitro/types\";\n\n// https://vite.dev/guide/api-environment-plugins\n// https://vite.dev/guide/api-environment-frameworks.html\n\nconst DEFAULT_EXTENSIONS = [\".ts\", \".js\", \".mts\", \".mjs\", \".tsx\", \".jsx\"];\n\nconst debug = process.env.NITRO_DEBUG\n  ? (...args: any[]) => console.log(\"[nitro]\", ...args)\n  : () => {};\n\nexport function nitro(pluginConfig: NitroPluginConfig = {}): VitePlugin[] {\n  if ((globalThis as any).__nitro_build__) {\n    // We are in `nitro build` context. Nitro injects vite plugin itself\n    return [];\n  }\n  const ctx: NitroPluginContext = createContext(pluginConfig);\n  return [\n    nitroInit(ctx),\n    nitroEnv(ctx),\n    nitroMain(ctx),\n    nitroPrepare(ctx),\n    nitroService(ctx),\n    nitroPreviewPlugin(ctx),\n    pluginConfig.experimental?.vite?.assetsImport !== false &&\n      assetsPlugin({\n        experimental: {\n          // See https://github.com/hi-ogawa/vite-plugins/pull/1289\n          clientBuildFallback: false,\n        },\n      }),\n  ].filter(Boolean) as VitePlugin[];\n}\n\nfunction nitroInit(ctx: NitroPluginContext): VitePlugin {\n  return {\n    name: \"nitro:init\",\n    sharedDuringBuild: true,\n    apply: (_config, configEnv) => !configEnv.isPreview,\n\n    async config(config, configEnv) {\n      ctx._isRolldown = !!(this.meta as Record<string, string>).rolldownVersion;\n      if (!ctx._initialized) {\n        debug(\"[init] Initializing nitro\");\n        ctx._initialized = true;\n        await setupNitroContext(ctx, configEnv, config);\n      }\n    },\n\n    applyToEnvironment(env) {\n      if (env.name === \"nitro\" && ctx.nitro?.options.dev) {\n        debug(\"[init] Adding rollup plugins for dev\");\n        const plugins =\n          (ctx.bundlerConfig?.rolldownConfig?.plugins as VitePlugin[]) ||\n          (ctx.bundlerConfig?.rollupConfig?.plugins as VitePlugin[]) ||\n          [];\n        return [...(plugins || [])];\n      }\n    },\n  };\n}\n\nfunction nitroEnv(ctx: NitroPluginContext): VitePlugin {\n  return {\n    name: \"nitro:env\",\n    sharedDuringBuild: true,\n    apply: (_config, configEnv) => !configEnv.isPreview,\n\n    async config(userConfig, _configEnv) {\n      debug(\"[env]  Extending config (environments)\");\n      const environments: Record<string, EnvironmentOptions> = {\n        ...createServiceEnvironments(ctx),\n        nitro: createNitroEnvironment(ctx),\n      };\n      environments.client = {\n        consumer: userConfig.environments?.client?.consumer ?? \"client\",\n        build: {\n          rollupOptions: {\n            input:\n              userConfig.environments?.client?.build?.rollupOptions?.input ??\n              useNitro(ctx).options.renderer?.template,\n          },\n        },\n      };\n      debug(\"[env]  Environments:\", Object.keys(environments).join(\", \"));\n      return {\n        environments,\n      };\n    },\n\n    configEnvironment(name, config) {\n      if (config.consumer === \"client\") {\n        debug(\"[env]  Configuring client environment\", name === \"client\" ? \"\" : ` (${name})`);\n        config.build!.emptyOutDir = false;\n        config.build!.outDir = useNitro(ctx).options.output.publicDir;\n        config.build!.copyPublicDir ??= false;\n        return;\n      }\n\n      // Skip if already registered as a service\n      if (name === \"nitro\" || ctx.services[name]) {\n        return;\n      }\n\n      // Auto-register server consumer environments as services\n      const entry = getEntry(\n        config.build?.rolldownOptions?.input || config.build?.rollupOptions?.input\n      );\n      if (typeof entry !== \"string\") {\n        return;\n      }\n\n      // Resolve and register as a service\n      const resolvedEntry =\n        resolveModulePath(entry, {\n          from: [ctx.nitro!.options.rootDir, ...ctx.nitro!.options.scanDirs],\n          extensions: DEFAULT_EXTENSIONS,\n          suffixes: [\"\", \"/index\"],\n          try: true,\n        }) || entry;\n\n      ctx.services[name] = { entry: resolvedEntry };\n      debug(`[env]  Auto-detected service \"${name}\" with entry: ${resolvedEntry}`);\n\n      // Return service environment configuration to merge\n      return createServiceEnvironment(ctx, name, { entry: resolvedEntry });\n    },\n\n    configResolved() {\n      // Setup default SSR renderer after all environments are configured\n      if (\n        !ctx.nitro!.options.renderer?.handler &&\n        !ctx.nitro!.options.renderer?.template &&\n        ctx.services.ssr?.entry\n      ) {\n        ctx.nitro!.options.renderer ??= {};\n        ctx.nitro!.options.renderer.handler = resolve(runtimeDir, \"internal/vite/ssr-renderer\");\n        ctx.nitro!.routing.sync();\n      }\n    },\n  };\n}\n\nfunction nitroMain(ctx: NitroPluginContext): VitePlugin {\n  return {\n    name: \"nitro:main\",\n    sharedDuringBuild: true,\n    apply: (_config, configEnv) => !configEnv.isPreview,\n\n    async config(userConfig, _configEnv) {\n      debug(\"[main] Extending config (appType, resolve, server)\");\n      if (!ctx.bundlerConfig) {\n        throw new Error(\"Bundler config is not initialized yet!\");\n      }\n      return {\n        appType: userConfig.appType || \"custom\",\n        resolve: {\n          // TODO: environment specific aliases not working\n          // https://github.com/vitejs/vite/pull/17583 (seems not effective)\n          alias: ctx.bundlerConfig.base.aliases,\n        },\n        builder: {\n          sharedConfigBuild: true,\n        },\n        server: {\n          port:\n            Number.parseInt(process.env.PORT || \"\") ||\n            userConfig.server?.port ||\n            useNitro(ctx).options.devServer?.port ||\n            3000,\n          // #3673, disable Vite's `cors` by default as Nitro handles all requests\n          cors: false,\n        },\n      };\n    },\n\n    buildApp: {\n      order: \"post\",\n      handler(builder) {\n        debug(\"[main] Building environments\");\n        return buildEnvironments(ctx, builder);\n      },\n    },\n\n    generateBundle: {\n      handler(_options, bundle) {\n        const environment = this.environment;\n        debug(\"[main] Generating manifest and entry points for environment:\", environment.name);\n        const serviceNames = Object.keys(ctx.services);\n        const isRegisteredService = serviceNames.includes(environment.name);\n\n        // Find entry point of this service\n        let entryFile: string | undefined;\n        for (const [_name, file] of Object.entries(bundle)) {\n          if (file.type === \"chunk\" && isRegisteredService && file.isEntry) {\n            if (entryFile === undefined) {\n              entryFile = file.fileName;\n            } else {\n              this.warn(`Multiple entry points found for service \"${environment.name}\"`);\n            }\n          }\n        }\n        if (isRegisteredService) {\n          if (entryFile === undefined) {\n            this.error(`No entry point found for service \"${this.environment.name}\".`);\n          }\n          ctx._entryPoints![this.environment.name] = entryFile!;\n        }\n      },\n    },\n\n    configureServer: (server) => {\n      debug(\"[main] Configuring dev server\");\n      return configureViteDevServer(ctx, server);\n    },\n\n    // Invalidate server-only modules and optionally reload the browser\n    // see: https://github.com/vitejs/vite/issues/19114\n    async hotUpdate({ server, modules, timestamp }) {\n      if (ctx.pluginConfig.experimental?.vite?.serverReload === false) {\n        return;\n      }\n      const env = this.environment;\n      if (env.config.consumer === \"client\") {\n        return;\n      }\n      const clientEnvs = Object.values(server.environments).filter(\n        (env) => env.config.consumer === \"client\"\n      );\n      const serverOnlyModules: EnvironmentModuleNode[] = [];\n      const sharedModules: EnvironmentModuleNode[] = [];\n      const invalidated = new Set<EnvironmentModuleNode>();\n      for (const mod of modules) {\n        if (mod.id && !clientEnvs.some((env) => env.moduleGraph.getModuleById(mod.id!))) {\n          serverOnlyModules.push(mod);\n          env.moduleGraph.invalidateModule(mod, invalidated, timestamp, false);\n        } else {\n          sharedModules.push(mod);\n        }\n      }\n      if (serverOnlyModules.length > 0) {\n        env.hot.send({ type: \"full-reload\" });\n        if (sharedModules.length === 0 && serverOnlyModules.some((m) => m.environment !== \"ssr\")) {\n          server.ws.send({ type: \"full-reload\" });\n        }\n        return sharedModules;\n      }\n    },\n  };\n}\n\nfunction nitroPrepare(ctx: NitroPluginContext): VitePlugin {\n  return {\n    name: \"nitro:prepare\",\n    sharedDuringBuild: true,\n    applyToEnvironment: (env) => env.name === \"nitro\",\n\n    buildApp: {\n      // Clean the output directory before any environment is built\n      order: \"pre\",\n      async handler() {\n        debug(\"[prepare] Preparing output directory\");\n        const nitro = ctx.nitro!;\n        await prepare(nitro);\n      },\n    },\n  };\n}\n\nfunction nitroService(ctx: NitroPluginContext): VitePlugin {\n  return {\n    name: \"nitro:service\",\n    enforce: \"pre\",\n    sharedDuringBuild: true,\n    applyToEnvironment: (env) => env.name === \"nitro\",\n\n    resolveId: {\n      filter: { id: /^#nitro-vite-setup$/ },\n      async handler(id) {\n        // Virtual modules\n        if (id === \"#nitro-vite-setup\") {\n          return { id, moduleSideEffects: true };\n        }\n      },\n    },\n\n    load: {\n      filter: { id: /^#nitro-vite-setup$/ },\n      async handler(id) {\n        // Virtual modules\n        if (id === \"#nitro-vite-setup\") {\n          return prodSetup(ctx);\n        }\n      },\n    },\n  };\n}\n\n// --- internal helpers ---\n\nfunction createContext(pluginConfig: NitroPluginConfig): NitroPluginContext {\n  return {\n    pluginConfig,\n    services: { ...pluginConfig.experimental?.vite?.services },\n    _entryPoints: {},\n  };\n}\n\nfunction useNitro(ctx: NitroPluginContext) {\n  if (!ctx.nitro) {\n    throw new Error(\"Nitro instance is not initialized yet.\");\n  }\n  return ctx.nitro;\n}\n\nasync function setupNitroContext(\n  ctx: NitroPluginContext,\n  configEnv: ConfigEnv,\n  userConfig: UserConfig\n) {\n  // Nitro config overrides\n  const nitroConfig: NitroConfig = {\n    dev: configEnv.command === \"serve\",\n    builder: \"vite\",\n    rootDir: userConfig.root,\n    ...defu(\n      ctx.pluginConfig,\n      (ctx.pluginConfig as any).config, // TODO: Remove shortly\n      userConfig.nitro\n    ),\n  };\n\n  // Register Nitro modules from Vite plugins\n  nitroConfig.modules ??= [];\n  for (const plugin of flattenPlugins(userConfig.plugins || [])) {\n    if (plugin.nitro) {\n      nitroConfig.modules.push(plugin.nitro);\n    }\n  }\n\n  // @see https://vite.dev/guide/env-and-mode#env-files\n  const dotenvFileNames = [\".env\", \".env.local\"];\n  if (configEnv.mode) {\n    dotenvFileNames.push(`.env.${configEnv.mode}`, `.env.${configEnv.mode}.local`);\n  }\n\n  // Initialize a new Nitro instance\n  ctx.nitro =\n    ctx.pluginConfig._nitro ||\n    (await createNitro(nitroConfig, { dotenv: { fileName: dotenvFileNames } }));\n\n  // Config ssr env as a fetchable ssr service\n  if (!ctx.services?.ssr) {\n    if (userConfig.environments?.ssr === undefined) {\n      const ssrEntry = resolveModulePath(\"./entry-server\", {\n        from: [\"app\", \"src\", \"\"].flatMap((d) =>\n          [ctx.nitro!.options.rootDir, ...ctx.nitro!.options.scanDirs].map((s) => join(s, d) + \"/\")\n        ),\n        extensions: DEFAULT_EXTENSIONS,\n        try: true,\n      });\n      if (ssrEntry) {\n        ctx.services.ssr = { entry: ssrEntry };\n        ctx.nitro!.logger.info(`Using \\`${prettyPath(ssrEntry)}\\` as vite ssr entry.`);\n      }\n    } else {\n      let ssrEntry = getEntry(userConfig.environments.ssr.build?.rollupOptions?.input);\n      if (typeof ssrEntry === \"string\") {\n        ssrEntry =\n          resolveModulePath(ssrEntry, {\n            from: [ctx.nitro.options.rootDir, ...ctx.nitro.options.scanDirs],\n            extensions: DEFAULT_EXTENSIONS,\n            suffixes: [\"\", \"/index\"],\n            try: true,\n          }) || ssrEntry;\n        ctx.services.ssr = { entry: ssrEntry };\n      }\n    }\n  }\n  if (\n    ctx.nitro.options.serverEntry &&\n    ctx.nitro.options.serverEntry.handler === ctx.services.ssr?.entry\n  ) {\n    ctx.nitro.logger.warn(\n      `Nitro server entry and Vite SSR both set to ${prettyPath(ctx.services.ssr.entry)}. Use a separate SSR entry (e.g. \\`src/server.ts\\`).`\n    );\n    ctx.nitro.options.serverEntry = false;\n  }\n\n  // Determine default Vite dist directory\n  const publicDistDir = (ctx._publicDistDir =\n    userConfig.build?.outDir || resolve(ctx.nitro.options.buildDir, \"vite/public\"));\n  ctx.nitro.options.publicAssets.push({\n    dir: publicDistDir,\n    maxAge: 0,\n    baseURL: \"/\",\n    fallthrough: true,\n  });\n\n  // Nitro Vite Production Runtime\n  if (!ctx.nitro.options.dev) {\n    ctx.nitro.options.unenv.push({\n      meta: { name: \"nitro-vite\" },\n      polyfill: [\"#nitro-vite-setup\"],\n    });\n  }\n\n  // Call build:before hook **before resolving rollup config** for compatibility\n  await ctx.nitro.hooks.callHook(\"build:before\", ctx.nitro);\n\n  // Resolve common rollup options\n  ctx.bundlerConfig = await getBundlerConfig(ctx);\n\n  // Call rollup:before hook to allow modifying rollup config\n  await ctx.nitro.hooks.callHook(\n    \"rollup:before\",\n    ctx.nitro,\n    ctx.bundlerConfig.rollupConfig || (ctx.bundlerConfig.rolldownConfig as any)\n  );\n\n  // Warm up env runner for dev\n  if (ctx.nitro.options.dev) {\n    await initEnvRunner(ctx);\n  }\n\n  // Attach nitro.fetch to env runner\n  ctx.nitro.fetch = (req) => getEnvRunner(ctx).fetch(req);\n\n  // Create dev app\n  if (ctx.nitro.options.dev && !ctx.devApp) {\n    ctx.devApp = new NitroDevApp(ctx.nitro);\n  }\n\n  // Cleanup resources after close {\n  ctx.nitro.hooks.hook(\"close\", async () => {\n    if (ctx._envRunner) {\n      await ctx._envRunner.close();\n    }\n  });\n}\n\nfunction getEntry(input: InputOption | undefined): string | undefined {\n  if (typeof input === \"string\") {\n    return input;\n  } else if (Array.isArray(input) && input.length > 0) {\n    return input[0];\n  } else if (input && \"index\" in input) {\n    return input.index as string;\n  }\n}\n\nfunction flattenPlugins(plugins: PluginOption[]): VitePlugin[] {\n  return plugins\n    .flatMap((plugin) => (Array.isArray(plugin) ? flattenPlugins(plugin) : [plugin]))\n    .filter((p) => p && !(p instanceof Promise)) as VitePlugin[];\n}\n"
  },
  {
    "path": "src/build/vite/preview.ts",
    "content": "import type { Plugin as VitePlugin } from \"vite\";\nimport type { NitroPluginContext } from \"./types.ts\";\nimport { startPreview } from \"../../preview.ts\";\n\nexport function nitroPreviewPlugin(ctx: NitroPluginContext): VitePlugin {\n  return {\n    name: \"nitro:preview\",\n    apply: (_config, configEnv) => !!configEnv.isPreview,\n\n    config(config) {\n      return {\n        preview: {\n          port: config.preview?.port || 3000,\n        },\n      };\n    },\n\n    async configurePreviewServer(server) {\n      // Init Nitro preview handler\n      const preview = await startPreview({\n        rootDir: server.config.root,\n        loader: { nodeServer: server.httpServer },\n      });\n\n      // Close preview server when Vite's preview server is closed\n      server.httpServer.once(\"close\", async () => {\n        await preview.close();\n      });\n\n      // Handle all requests with Nitro preview handler (also handles production static assets)\n      const { NodeRequest, sendNodeResponse } = await import(\"srvx/node\");\n      server.middlewares.use(async (req, res, next) => {\n        const nodeReq = new NodeRequest({ req, res });\n        const previewRes: Response = await preview.fetch(nodeReq);\n        await sendNodeResponse(res, previewRes).catch(next);\n      });\n\n      // Handle WebSocket upgrade requests with Nitro preview handler if supported\n      if (preview.upgrade) {\n        server.httpServer.on(\"upgrade\", (req, socket, head) => {\n          preview.upgrade!(req, socket, head);\n        });\n      }\n    },\n  } satisfies VitePlugin;\n}\n"
  },
  {
    "path": "src/build/vite/prod.ts",
    "content": "import type { ViteBuilder } from \"vite\";\nimport type { NitroPluginContext } from \"./types.ts\";\n\nimport { basename, dirname, resolve } from \"pathe\";\nimport { formatCompatibilityDate } from \"compatx\";\nimport { colors as C } from \"consola/utils\";\nimport { copyPublicAssets, prerender } from \"../../builder.ts\";\nimport { existsSync } from \"node:fs\";\nimport { writeBuildInfo } from \"../info.ts\";\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { isTest, isCI } from \"std-env\";\nimport type { RolldownOutput } from \"rolldown\";\n\nconst BuilderNames = {\n  nitro: C.magenta(\"Nitro\"),\n  client: C.green(\"Client\"),\n  ssr: C.blue(\"SSR\"),\n} as Record<string, string>;\n\nexport async function buildEnvironments(ctx: NitroPluginContext, builder: ViteBuilder) {\n  const nitro = ctx.nitro!;\n\n  // ----------------------------------------------\n  // Stage 1: Build all environments before Nitro\n  // ----------------------------------------------\n\n  for (const [envName, env] of Object.entries(builder.environments)) {\n    // prettier-ignore\n    const fmtName = BuilderNames[envName] || (envName.length <= 3 ? envName.toUpperCase() : envName[0].toUpperCase() + envName.slice(1));\n    if (envName === \"nitro\" || !env.config.build.rollupOptions.input || env.isBuilt) {\n      if (![\"nitro\", \"ssr\", \"client\"].includes(envName)) {\n        nitro.logger.info(\n          env.isBuilt\n            ? `Skipping ${fmtName} (already built)`\n            : `Skipping ${fmtName} (no input defined)`\n        );\n      }\n      continue;\n    }\n    if (!isTest && !isCI) console.log();\n    nitro.logger.start(`Building [${fmtName}]`);\n    await builder.build(env);\n  }\n\n  // Use transformed client input for renderer template generation\n  const nitroOptions = ctx.nitro!.options;\n  const clientInput = builder.environments.client?.config?.build?.rollupOptions?.input;\n  if (nitroOptions.renderer?.template && nitroOptions.renderer?.template === clientInput) {\n    const outputPath = resolve(nitroOptions.output.publicDir, basename(clientInput as string));\n    if (existsSync(outputPath)) {\n      const html = await readFile(outputPath, \"utf8\").then((r) =>\n        r.replace(\n          \"<!--ssr-outlet-->\",\n          `{{{ globalThis.__nitro_vite_envs__?.[\"ssr\"]?.fetch($REQUEST) || \"\" }}}`\n        )\n      );\n      await rm(outputPath);\n      const tmp = resolve(nitroOptions.buildDir, \"vite/index.html\");\n      await mkdir(dirname(tmp), { recursive: true });\n      await writeFile(tmp, html, \"utf8\");\n      nitroOptions.renderer.template = tmp;\n    }\n  }\n\n  // Extended builder API by assets plugin\n  // https://github.com/hi-ogawa/vite-plugins/pull/1288\n  await builder.writeAssetsManifest?.();\n\n  // ----------------------------------------------\n  // Stage 2: Build Nitro\n  // ----------------------------------------------\n\n  if (!isTest && !isCI) console.log();\n  const buildInfo = [\n    [\"preset\", nitro.options.preset],\n    [\"compatibility\", formatCompatibilityDate(nitro.options.compatibilityDate)],\n  ].filter((e) => e[1]);\n  nitro.logger.start(\n    `Building [${BuilderNames.nitro}] ${C.dim(`(${buildInfo.map(([k, v]) => `${k}: \\`${v}\\``).join(\", \")})`)}`\n  );\n\n  // Copy public assets to the final output directory\n  await copyPublicAssets(nitro);\n\n  // Add route rule for asset dirs\n  const assetDirs = new Set(\n    Object.values(builder.environments)\n      .filter((env) => env.config.consumer === \"client\")\n      .map((env) => env.config.build.assetsDir)\n      .filter(Boolean) as string[]\n  );\n  for (const assetsDir of assetDirs) {\n    if (!existsSync(resolve(nitro.options.output.publicDir, assetsDir))) {\n      continue;\n    }\n    const rule = (ctx.nitro!.options.routeRules[`/${assetsDir}/**`] ??= {});\n    if (!rule.headers?.[\"cache-control\"]) {\n      rule.headers = {\n        ...rule.headers,\n        \"cache-control\": `public, max-age=31536000, immutable`,\n      };\n    }\n  }\n  ctx.nitro!.routing.sync();\n\n  // Prerender routes if configured\n  await prerender(nitro);\n\n  // Build the Nitro server bundle\n  const output = (await builder.build(builder.environments.nitro)) as RolldownOutput;\n\n  // Close the Nitro instance\n  await nitro.close();\n\n  // Call compiled hook\n  await nitro.hooks.callHook(\"compiled\", nitro);\n\n  // Write build info\n  await writeBuildInfo(nitro, output);\n\n  // Show deploy and preview commands\n  if (!isTest && !isCI) console.log();\n  nitro.logger.success(\"You can preview this build using `npx vite preview`\");\n  if (nitro.options.commands.deploy) {\n    nitro.logger.success(\"You can deploy this build using `npx nitro deploy --prebuilt`\");\n  }\n}\n\nexport function prodSetup(ctx: NitroPluginContext): string {\n  const serviceNames = Object.keys(ctx.services);\n\n  const serviceEntries = serviceNames.map((name) => {\n    const entry = resolve(\n      ctx.nitro!.options.buildDir,\n      \"vite/services\",\n      name,\n      ctx._entryPoints[name]\n    );\n    return [name, entry];\n  });\n\n  return /* js */ `\nfunction lazyService(loader) {\n  let promise, mod\n  return {\n    fetch(req) {\n      if (mod) { return mod.fetch(req) }\n      if (!promise) {\n        promise = loader().then(_mod => (mod = _mod.default || _mod))\n      }\n      return promise.then(mod => mod.fetch(req))\n    }\n  }\n}\n\nconst services = {\n${serviceEntries\n  .map(\n    ([name, entry]) =>\n      /* js */ `[${JSON.stringify(name)}]: lazyService(() => import(${JSON.stringify(entry)}))`\n  )\n  .join(\",\\n\")}\n};\n\nglobalThis.__nitro_vite_envs__ = services;\n  `;\n}\n"
  },
  {
    "path": "src/build/vite/types.ts",
    "content": "import type { TransformResult } from \"vite\";\nimport type { getBundlerConfig } from \"./bundler.ts\";\nimport type { Nitro, NitroConfig, NitroModule } from \"nitro/types\";\nimport type { RunnerManager } from \"env-runner\";\nimport type { NitroDevApp } from \"../../dev/app.ts\";\n\ndeclare module \"vite\" {\n  interface UserConfig {\n    /**\n     * Nitro Vite Plugin options.\n     */\n    nitro?: NitroConfig;\n  }\n\n  interface Plugin {\n    nitro?: NitroModule;\n  }\n}\n\nexport interface NitroPluginConfig extends NitroConfig {\n  /**\n   * @internal Use preinitialized Nitro instance for the plugin.\n   */\n  _nitro?: Nitro;\n\n  experimental?: NitroConfig[\"experimental\"] & {\n    vite: {\n      /**\n       * @experimental Enable `?assets` import proposed by https://github.com/vitejs/vite/discussions/20913\n       * @default true\n       */\n      assetsImport?: boolean;\n\n      /**\n       *\n       * Invalidate server-only modules and optionally reload the browser when a server-only module is updated.\n       *\n       * @default true\n       */\n      serverReload?: boolean;\n\n      /**\n       * Additional Vite environment services to register.\n       */\n      services?: Record<string, ServiceConfig>;\n    };\n  };\n}\n\nexport interface ServiceConfig {\n  entry: string;\n}\n\nexport interface NitroPluginContext {\n  nitro?: Nitro;\n  pluginConfig: NitroPluginConfig;\n  bundlerConfig?: Awaited<ReturnType<typeof getBundlerConfig>>;\n  devApp?: NitroDevApp;\n  services: Record<string, ServiceConfig>;\n\n  _isRolldown?: boolean;\n  _initialized?: boolean;\n  _envRunner?: RunnerManager;\n  _initPromise?: Promise<RunnerManager>;\n  _viteEnvs?: Map<string, string>;\n  _transformRequest?: (id: string) => Promise<TransformResult | null | undefined>;\n  _publicDistDir?: string;\n  _entryPoints: Record<string, string>;\n}\n"
  },
  {
    "path": "src/builder.ts",
    "content": "// Core\nexport { createNitro } from \"./nitro.ts\";\n\n// Config loader\nexport { loadOptions } from \"./config/loader.ts\";\n\n// Build\nexport { build } from \"./build/build.ts\";\nexport { copyPublicAssets } from \"./build/assets.ts\";\nexport { prepare } from \"./build/prepare.ts\";\nexport { writeTypes } from \"./build/types.ts\";\nexport { getBuildInfo } from \"./build/info.ts\";\n\n// Dev server\nexport { createDevServer } from \"./dev/server.ts\";\n\n// Prerender\nexport { prerender } from \"./prerender/prerender.ts\";\n\n// Tasks API\nexport { runTask, listTasks } from \"./task.ts\";\n"
  },
  {
    "path": "src/cli/commands/build.ts",
    "content": "import { defineCommand } from \"citty\";\nimport type { DateString } from \"compatx\";\nimport { build, copyPublicAssets, createNitro, prepare, prerender } from \"nitro/builder\";\nimport { resolve } from \"pathe\";\nimport { commonArgs } from \"../common.ts\";\n\nexport const buildArgs = {\n  ...commonArgs,\n  minify: {\n    type: \"boolean\",\n    description:\n      \"Minify the output (overrides preset defaults you can also use `--no-minify` to disable).\",\n  },\n  preset: {\n    type: \"string\",\n    description: \"The build preset to use (you can also use `NITRO_PRESET` environment variable).\",\n  },\n  builder: {\n    type: \"string\",\n    description: \"The builder to use (you can also use `NITRO_BUILDER` environment variable).\",\n  },\n  compatibilityDate: {\n    type: \"string\",\n    description:\n      \"The date to use for preset compatibility (you can also use `NITRO_COMPATIBILITY_DATE` environment variable).\",\n  },\n} as const;\n\nexport default defineCommand({\n  meta: {\n    name: \"build\",\n    description: \"Build nitro project for production\",\n  },\n  args: buildArgs,\n  async run({ args }) {\n    const rootDir = resolve((args.dir || args._dir || \".\") as string);\n    const nitro = await createNitro(\n      {\n        rootDir,\n        dev: false,\n        minify: args.minify,\n        preset: args.preset,\n        builder: args.builder as \"rollup\" | \"rolldown\" | \"vite\",\n      },\n      {\n        compatibilityDate: args.compatibilityDate as DateString,\n      }\n    );\n    await prepare(nitro);\n    await copyPublicAssets(nitro);\n    await prerender(nitro);\n    await build(nitro);\n    await nitro.close();\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/deploy.ts",
    "content": "import { defineCommand } from \"citty\";\nimport { relative, resolve } from \"pathe\";\nimport consola from \"consola\";\nimport { execSync } from \"node:child_process\";\nimport { getBuildInfo } from \"../../build/info.ts\";\nimport buildCmd, { buildArgs } from \"./build.ts\";\n\nexport default defineCommand({\n  meta: {\n    name: \"deploy\",\n    description: \"Build and deploy nitro project for production\",\n  },\n  args: {\n    ...buildArgs,\n    prebuilt: {\n      type: \"boolean\",\n      description: \"Skip the build step and deploy the existing build\",\n    },\n  },\n  async run(ctx) {\n    (globalThis as any).__nitroDeploying__ = true;\n    if (!ctx.args.prebuilt) {\n      await buildCmd.run!(ctx as any);\n    }\n    if ((globalThis as any).__nitroDeployed__) {\n      return;\n    }\n    const rootDir = resolve((ctx.args.dir || ctx.args._dir || \".\") as string);\n    const { buildInfo, outputDir } = await getBuildInfo(rootDir);\n    if (!buildInfo) {\n      // throw new Error(\"No build info found, cannot deploy.\");\n      consola.error(\"No build info found, cannot deploy.\");\n      process.exit(1);\n    }\n    if (!buildInfo.commands?.deploy) {\n      consola.error(\n        `The \\`${buildInfo.preset}\\` preset does not have a default deploy command.\\n\\nTry using a different preset with the \\`--preset\\` option, or configure a deploy command in the Nitro config, or deploy manually.`\n      );\n      process.exit(1);\n    }\n\n    const extraArgs =\n      ctx.rawArgs.indexOf(\"--\") !== -1\n        ? ctx.rawArgs.slice(ctx.rawArgs.indexOf(\"--\") + 1).join(\" \")\n        : \"\";\n\n    const deployCommand =\n      buildInfo.commands.deploy.replace(\n        /([\\s:])\\.\\/(\\S*)/g,\n        `$1${relative(process.cwd(), outputDir)}/$2`\n      ) + (extraArgs ? ` ${extraArgs}` : \"\");\n\n    consola.info(`$ ${deployCommand}`);\n    execSync(deployCommand, { stdio: \"inherit\" });\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/dev.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { build, createNitro, prepare } from \"nitro/builder\";\nimport { resolve } from \"pathe\";\nimport { commonArgs } from \"../common.ts\";\nimport { NitroDevServer } from \"../../dev/server.ts\";\n\nconst hmrKeyRe = /^runtimeConfig\\.|routeRules\\./;\n\nexport default defineCommand({\n  meta: {\n    name: \"dev\",\n    description: \"Start the development server\",\n  },\n  args: {\n    ...commonArgs,\n    port: { type: \"string\", description: \"specify port\" },\n    host: { type: \"string\", description: \"specify hostname \" },\n  },\n  async run({ args }) {\n    const rootDir = resolve((args.dir || args._dir || \".\") as string);\n    let nitro: Nitro;\n    const reload = async () => {\n      if (nitro) {\n        consola.info(\"Restarting dev server...\");\n        if (\"unwatch\" in nitro.options._c12) {\n          await nitro.options._c12.unwatch();\n        }\n        await nitro.close();\n      }\n      nitro = await createNitro(\n        {\n          rootDir,\n          dev: true,\n          _cli: { command: \"dev\" },\n        },\n        {\n          watch: true,\n          c12: {\n            async onUpdate({ getDiff, newConfig }) {\n              const diff = getDiff();\n\n              if (diff.length === 0) {\n                return; // No changes\n              }\n\n              consola.info(\n                \"Nitro config updated:\\n\" + diff.map((entry) => `  ${entry.toString()}`).join(\"\\n\")\n              );\n\n              await (diff.every((e) => hmrKeyRe.test(e.key))\n                ? nitro.updateConfig(newConfig.config || {}) // Hot reload\n                : reload()); // Full reload\n            },\n          },\n        }\n      );\n      nitro.hooks.hookOnce(\"restart\", reload);\n      const server = new NitroDevServer(nitro);\n\n      await server.listen({\n        port: args.port || nitro.options.devServer.port,\n        hostname: args.host || nitro.options.devServer.hostname,\n      });\n      await prepare(nitro);\n      await build(nitro);\n    };\n    await reload();\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/docs.ts",
    "content": "import { execSync } from \"node:child_process\";\nimport { defineCommand } from \"citty\";\n\nexport default defineCommand({\n  meta: {\n    name: \"docs\",\n    description: \"Explore Nitro documentation\",\n  },\n  args: {\n    page: { type: \"string\", description: \"Page path to open\" },\n  },\n  run({ rawArgs }) {\n    const runner = (\n      [\n        [\"bun\", \"x\"],\n        [\"pnpm\", \"dlx\"],\n        [\"npm\", \"x\"],\n      ] as const\n    ).find(([pkg]) => {\n      try {\n        execSync(`${pkg} -v`, { stdio: \"ignore\" });\n        return true;\n      } catch {}\n    }) || [\"npm\", \"x\"];\n    const runnerCmd = runner.join(\" \");\n    const docsDir = new URL(\"../../../skills/nitro/docs\", import.meta.url).pathname;\n    const args = rawArgs?.join(\" \") || \"\";\n    execSync(`${runnerCmd} mdzilla ${docsDir}${args ? ` ${args}` : \"\"}`, {\n      stdio: \"inherit\",\n    });\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/prepare.ts",
    "content": "import { defineCommand } from \"citty\";\nimport { createNitro, writeTypes } from \"nitro/builder\";\nimport { resolve } from \"pathe\";\nimport { commonArgs } from \"../common.ts\";\n\nexport default defineCommand({\n  meta: {\n    name: \"prepare\",\n    description: \"Generate types for the project\",\n  },\n  args: {\n    ...commonArgs,\n  },\n  async run({ args }) {\n    const rootDir = resolve((args.dir || args._dir || \".\") as string);\n    const nitro = await createNitro({ rootDir });\n    await writeTypes(nitro);\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/preview.ts",
    "content": "import { defineCommand } from \"citty\";\nimport { resolve } from \"pathe\";\nimport { commonArgs } from \"../common.ts\";\nimport { startPreview } from \"../../preview.ts\";\nimport { serve } from \"srvx\";\nimport { log } from \"srvx/log\";\n\nexport default defineCommand({\n  meta: {\n    name: \"preview\",\n    description: \"Start a local server to preview the built server\",\n  },\n  args: {\n    ...commonArgs,\n    port: { type: \"string\", description: \"specify port\" },\n    host: { type: \"string\", description: \"specify hostname\" },\n  },\n  async run({ args }) {\n    const rootDir = resolve((args.dir || args._dir || \".\") as string);\n\n    const server = serve({\n      fetch(req) {\n        return preview.fetch(req);\n      },\n      middleware: [log()],\n      gracefulShutdown: false,\n      port: args.port,\n      hostname: args.host,\n    });\n\n    const preview = await startPreview({\n      rootDir,\n      loader: { srvxServer: server },\n    });\n\n    if (preview.upgrade) {\n      server.node?.server?.on(\"upgrade\", (req, socket, head) => {\n        preview.upgrade!(req, socket, head);\n      });\n    }\n\n    process.on(\"SIGINT\", async () => {\n      await server.close();\n      await preview.close();\n      process.exit(0);\n    });\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/task/index.ts",
    "content": "import { defineCommand } from \"citty\";\n\nexport default defineCommand({\n  meta: {\n    name: \"task\",\n    description: \"Operate in nitro tasks (experimental)\",\n  },\n  subCommands: {\n    list: () => import(\"./list.ts\").then((r) => r.default),\n    run: () => import(\"./run.ts\").then((r) => r.default),\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/task/list.ts",
    "content": "import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { listTasks, loadOptions } from \"nitro/builder\";\nimport { resolve } from \"pathe\";\n\nexport default defineCommand({\n  meta: {\n    name: \"run\",\n    description: \"List available tasks (experimental)\",\n  },\n  args: {\n    dir: {\n      type: \"string\",\n      description: \"project root directory\",\n    },\n  },\n  async run({ args }) {\n    const cwd = resolve((args.dir || args.cwd || \".\") as string);\n    const options = await loadOptions({ rootDir: cwd }).catch(() => undefined);\n\n    const tasks = await listTasks({\n      cwd,\n      buildDir: options?.buildDir || \".nitro\",\n    });\n    for (const [name, task] of Object.entries(tasks)) {\n      consola.log(` - \\`${name}\\`${task.meta?.description ? ` - ${task.meta.description}` : \"\"}`);\n    }\n  },\n});\n"
  },
  {
    "path": "src/cli/commands/task/run.ts",
    "content": "import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport destr from \"destr\";\nimport { loadOptions, runTask } from \"nitro/builder\";\nimport { resolve } from \"pathe\";\n\nexport default defineCommand({\n  meta: {\n    name: \"run\",\n    description: \"Run a runtime task in the currently running dev server (experimental)\",\n  },\n  args: {\n    name: {\n      type: \"positional\",\n      description: \"task name\",\n      required: true,\n    },\n    dir: {\n      type: \"string\",\n      description: \"project root directory\",\n    },\n    payload: {\n      type: \"string\",\n      description: \"payload json to pass to the task\",\n    },\n  },\n  async run({ args }) {\n    const cwd = resolve((args.dir || args.cwd || \".\") as string);\n    const options = await loadOptions({ rootDir: cwd }).catch(() => undefined);\n\n    consola.info(`Running task \\`${args.name}\\`...`);\n    let payload: any = destr(args.payload || \"{}\");\n    if (typeof payload !== \"object\") {\n      consola.error(`Invalid payload: \\`${args.payload}\\` (it should be a valid JSON object)`);\n      payload = undefined;\n    }\n    try {\n      const { result } = await runTask(\n        {\n          name: args.name,\n          context: {},\n          payload,\n        },\n        {\n          cwd,\n          buildDir: options?.buildDir || \".nitro\",\n        }\n      );\n      consola.success(\"Result:\", result);\n    } catch (error) {\n      consola.error(`Failed to run task \\`${args.name}\\`: ${error}`);\n      process.exit(1); // eslint-disable-line unicorn/no-process-exit\n    }\n  },\n});\n"
  },
  {
    "path": "src/cli/common.ts",
    "content": "import type { ArgsDef } from \"citty\";\n\nexport const commonArgs = {\n  dir: {\n    type: \"string\",\n    description: \"project root directory\",\n  },\n  _dir: {\n    type: \"positional\",\n    default: \".\",\n    description: \"project root directory (prefer using `--dir`)\",\n  },\n} satisfies ArgsDef;\n"
  },
  {
    "path": "src/cli/index.ts",
    "content": "#!/usr/bin/env node\nimport { defineCommand, runMain } from \"citty\";\nimport { version as nitroVersion } from \"nitro/meta\";\n\nconst main = defineCommand({\n  meta: {\n    name: \"nitro\",\n    description: \"Nitro CLI\",\n    version: nitroVersion,\n  },\n  subCommands: {\n    dev: () => import(\"./commands/dev.ts\").then((r) => r.default),\n    build: () => import(\"./commands/build.ts\").then((r) => r.default),\n    deploy: () => import(\"./commands/deploy.ts\").then((r) => r.default),\n    prepare: () => import(\"./commands/prepare.ts\").then((r) => r.default),\n    task: () => import(\"./commands/task/index.ts\").then((r) => r.default),\n    preview: () => import(\"./commands/preview.ts\").then((r) => r.default),\n    docs: () => import(\"./commands/docs.ts\").then((r) => r.default),\n  },\n});\n\nrunMain(main);\n"
  },
  {
    "path": "src/config/defaults.ts",
    "content": "import type { NitroConfig } from \"nitro/types\";\nimport { isDebug, isTest } from \"std-env\";\nimport { version as nitroVersion } from \"nitro/meta\";\n\nexport const NitroDefaults: NitroConfig = {\n  // General\n  compatibilityDate: \"latest\",\n  debug: isDebug,\n  logLevel: isTest ? 1 : 3,\n  runtimeConfig: { app: {}, nitro: {} },\n\n  // Dirs\n  serverDir: false,\n  scanDirs: [],\n  buildDir: `node_modules/.nitro`,\n  output: {\n    dir: \"{{ rootDir }}/.output\",\n    serverDir: \"{{ output.dir }}/server\",\n    publicDir: \"{{ output.dir }}/public\",\n  },\n\n  // Features\n  features: {},\n  experimental: {},\n  future: {},\n  storage: {},\n  devStorage: {},\n  publicAssets: [],\n  serverAssets: [],\n  plugins: [],\n  tasks: {},\n  scheduledTasks: {},\n  imports: false,\n  virtual: {},\n  compressPublicAssets: false,\n  ignore: [],\n  wasm: {},\n\n  // Dev\n  dev: false,\n  devServer: { watch: [] },\n  watchOptions: { ignoreInitial: true },\n  devProxy: {},\n\n  // Logging\n  logging: {\n    compressedSizes: true,\n    buildSuccess: true,\n  },\n\n  // Routing\n  baseURL: process.env.NITRO_APP_BASE_URL || \"/\",\n  handlers: [],\n  devHandlers: [],\n  errorHandler: undefined,\n  routes: {},\n  routeRules: {},\n  prerender: {\n    autoSubfolderIndex: true,\n    concurrency: 1,\n    interval: 0,\n    retry: 3,\n    retryDelay: 500,\n    failOnError: false,\n    crawlLinks: false,\n    ignore: [],\n    routes: [],\n  },\n\n  // Builder\n  builder: undefined,\n  moduleSideEffects: [\"unenv/polyfill/\"],\n  replace: {},\n  node: true,\n  sourcemap: false,\n  traceDeps: [],\n\n  // Advanced\n  typescript: {\n    strict: true,\n    generateRuntimeConfigTypes: false,\n    generateTsConfig: false,\n    tsconfigPath: \"tsconfig.json\",\n    tsConfig: undefined,\n  },\n  hooks: {},\n  commands: {},\n\n  // Framework\n  framework: {\n    name: \"nitro\",\n    version: nitroVersion,\n  },\n};\n"
  },
  {
    "path": "src/config/loader.ts",
    "content": "import { loadConfig, watchConfig } from \"c12\";\nimport consola from \"consola\";\nimport { resolveCompatibilityDates } from \"compatx\";\nimport type { CompatibilityDateSpec } from \"compatx\";\nimport { klona } from \"klona/full\";\nimport type { PresetName } from \"../presets/index.ts\";\nimport type { LoadConfigOptions, NitroConfig, NitroOptions, NitroPresetMeta } from \"nitro/types\";\n\nimport { NitroDefaults } from \"./defaults.ts\";\n\n// Resolvers\nimport { resolveAssetsOptions } from \"./resolvers/assets.ts\";\nimport { resolveCompatibilityOptions } from \"./resolvers/compatibility.ts\";\nimport { resolveDatabaseOptions } from \"./resolvers/database.ts\";\nimport { resolveExportConditionsOptions } from \"./resolvers/export-conditions.ts\";\nimport { resolveImportsOptions } from \"./resolvers/imports.ts\";\nimport { resolveOpenAPIOptions } from \"./resolvers/open-api.ts\";\nimport { resolveTsconfig } from \"./resolvers/tsconfig.ts\";\nimport { resolvePathOptions } from \"./resolvers/paths.ts\";\nimport { resolveRouteRulesOptions } from \"./resolvers/route-rules.ts\";\nimport { resolveRuntimeConfigOptions } from \"./resolvers/runtime-config.ts\";\nimport { resolveStorageOptions } from \"./resolvers/storage.ts\";\nimport { resolveURLOptions } from \"./resolvers/url.ts\";\nimport { resolveErrorOptions } from \"./resolvers/error.ts\";\nimport { resolveUnenv } from \"./resolvers/unenv.ts\";\nimport { resolveBuilder } from \"./resolvers/builder.ts\";\n\nconst configResolvers = [\n  resolveCompatibilityOptions,\n  resolveTsconfig,\n  resolvePathOptions,\n  resolveImportsOptions,\n  resolveRouteRulesOptions,\n  resolveDatabaseOptions,\n  resolveExportConditionsOptions,\n  resolveRuntimeConfigOptions,\n  resolveOpenAPIOptions,\n  resolveURLOptions,\n  resolveAssetsOptions,\n  resolveStorageOptions,\n  resolveErrorOptions,\n  resolveUnenv,\n  resolveBuilder,\n] as const;\n\nexport async function loadOptions(\n  configOverrides: NitroConfig = {},\n  opts: LoadConfigOptions = {}\n): Promise<NitroOptions> {\n  const options = await _loadUserConfig(configOverrides, opts);\n  for (const resolver of configResolvers) {\n    await resolver(options);\n  }\n  return options;\n}\n\nasync function _loadUserConfig(\n  configOverrides: NitroConfig = {},\n  opts: LoadConfigOptions = {}\n): Promise<NitroOptions> {\n  // Load configuration and preset\n  configOverrides = klona(configOverrides);\n\n  // @ts-ignore\n  globalThis.defineNitroConfig = globalThis.defineNitroConfig || ((c) => c);\n\n  // Compatibility date\n  let compatibilityDate: CompatibilityDateSpec | undefined =\n    configOverrides.compatibilityDate ||\n    opts.compatibilityDate ||\n    ((process.env.NITRO_COMPATIBILITY_DATE ||\n      process.env.SERVER_COMPATIBILITY_DATE ||\n      process.env.COMPATIBILITY_DATE) as CompatibilityDateSpec);\n\n  // Preset resolver\n  const { resolvePreset } = await import(\"../presets/index.ts\");\n\n  // prettier-ignore\n  let preset: string | undefined = (configOverrides.preset as string) || process.env.NITRO_PRESET || process.env.SERVER_PRESET\n\n  const _dotenv = opts.dotenv ?? (configOverrides.dev && { fileName: [\".env\", \".env.local\"] });\n  const envName = opts.c12?.envName ?? (configOverrides.dev ? \"development\" : \"production\");\n  const loadedConfig = await (\n    opts.watch\n      ? watchConfig<NitroConfig & { _meta?: NitroPresetMeta }>\n      : loadConfig<NitroConfig & { _meta?: NitroPresetMeta }>\n  )({\n    name: \"nitro\",\n    cwd: configOverrides.rootDir,\n    dotenv: _dotenv,\n    envName,\n    extend: { extendKey: [\"extends\", \"preset\"] },\n    defaults: NitroDefaults,\n    async overrides({ rawConfigs }) {\n      // prettier-ignore\n      const getConf = <K extends keyof NitroConfig>(key: K) => (configOverrides[key] ?? (rawConfigs.main as NitroConfig)?.[key] ?? (rawConfigs.rc as NitroConfig)?.[key] ?? (rawConfigs.packageJson as NitroConfig)?.[key]) as NitroConfig[K];\n\n      if (!compatibilityDate) {\n        compatibilityDate = getConf(\"compatibilityDate\");\n      }\n\n      // prettier-ignore\n      const framework = getConf(\"framework\")\n      const isCustomFramework = framework?.name && framework.name !== \"nitro\";\n\n      if (!preset) {\n        preset = getConf(\"preset\");\n      }\n\n      if (configOverrides.dev) {\n        // Check if preset has compatible dev support\n        // Otherwise use default nitro-dev preset\n        preset =\n          preset && preset !== \"nitro-dev\"\n            ? await resolvePreset(preset, {\n                static: getConf(\"static\"),\n                dev: true,\n                compatibilityDate: compatibilityDate || \"latest\",\n              })\n                .then((p) => p?._meta?.name || \"nitro-dev\")\n                .catch(() => \"nitro-dev\")\n            : \"nitro-dev\";\n      } else if (!preset) {\n        // Auto detect production preset\n        preset = await resolvePreset(\"\" /* auto detect */, {\n          static: getConf(\"static\"),\n          dev: false,\n          compatibilityDate: compatibilityDate || \"latest\",\n        }).then((p) => p?._meta?.name);\n      }\n\n      return {\n        ...configOverrides,\n        preset,\n        typescript: {\n          generateRuntimeConfigTypes: !isCustomFramework,\n          ...getConf(\"typescript\"),\n          ...configOverrides.typescript,\n        },\n      };\n    },\n    async resolve(id: string) {\n      const preset = await resolvePreset(id, {\n        static: configOverrides.static,\n        compatibilityDate: compatibilityDate || \"latest\",\n        dev: configOverrides.dev,\n      });\n      if (preset) {\n        return {\n          config: klona(preset),\n        };\n      }\n    },\n    ...opts.c12,\n  });\n\n  const options = klona(loadedConfig.config) as NitroOptions;\n\n  options._config = configOverrides;\n  options._c12 = loadedConfig;\n\n  const _presetName =\n    (loadedConfig.layers || []).find((l) => l.config?._meta?.name)?.config?._meta?.name || preset;\n  options.preset = _presetName as PresetName;\n\n  options.compatibilityDate = resolveCompatibilityDates(\n    compatibilityDate,\n    options.compatibilityDate\n  );\n\n  if (options.dev && options.preset !== \"nitro-dev\") {\n    consola.info(`Using \\`${options.preset}\\` emulation in development mode.`);\n  }\n\n  return options;\n}\n"
  },
  {
    "path": "src/config/resolvers/assets.ts",
    "content": "import { existsSync } from \"node:fs\";\nimport { defu } from \"defu\";\nimport type { NitroOptions } from \"nitro/types\";\nimport { resolve } from \"pathe\";\nimport { withLeadingSlash, withoutTrailingSlash } from \"ufo\";\n\nexport async function resolveAssetsOptions(options: NitroOptions) {\n  // Public Assets\n  // 1. Normalize user paths\n  for (const publicAsset of options.publicAssets) {\n    publicAsset.dir = resolve(options.rootDir, publicAsset.dir);\n    publicAsset.baseURL = withLeadingSlash(withoutTrailingSlash(publicAsset.baseURL || \"/\"));\n  }\n  // 2. Add public/ directories from each layer\n  for (const dir of [options.rootDir, ...options.scanDirs]) {\n    const publicDir = resolve(dir, \"public\");\n    if (!existsSync(publicDir)) {\n      continue;\n    }\n    if (options.publicAssets.some((asset) => asset.dir === publicDir)) {\n      continue;\n    }\n    options.publicAssets.push({ dir: publicDir } as any);\n  }\n\n  // Server Assets\n  // 1. Normalize user paths\n  for (const serverAsset of options.serverAssets) {\n    serverAsset.dir = resolve(options.rootDir, serverAsset.dir);\n  }\n  // 2. Add server/ directory\n  options.serverAssets.push({\n    baseName: \"server\",\n    dir: resolve(options.rootDir, \"assets\"),\n  });\n\n  // Infer `fallthrough` and `maxAge` from publicAssets\n  for (const asset of options.publicAssets) {\n    asset.baseURL = asset.baseURL || \"/\";\n    const isTopLevel = asset.baseURL === \"/\";\n    asset.fallthrough = asset.fallthrough ?? isTopLevel;\n    const routeRule = options.routeRules[asset.baseURL + \"/**\"];\n    asset.maxAge = (routeRule?.cache as { maxAge: number })?.maxAge ?? asset.maxAge ?? 0;\n    if (asset.maxAge && !asset.fallthrough) {\n      options.routeRules[asset.baseURL + \"/**\"] = defu(routeRule, {\n        headers: {\n          \"cache-control\": `public, max-age=${asset.maxAge}, immutable`,\n        },\n      });\n    }\n  }\n}\n"
  },
  {
    "path": "src/config/resolvers/builder.ts",
    "content": "import { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport consola from \"consola\";\nimport type { NitroOptions } from \"nitro/types\";\nimport { resolve } from \"pathe\";\n\nconst VALID_BUILDERS = [\"rolldown\", \"rollup\", \"vite\"] as const;\n\nexport async function resolveBuilder(options: NitroOptions) {\n  // NITRO_BUILDER environment variable\n  options.builder ??= process.env.NITRO_BUILDER as any;\n\n  // Builder is explicitly set\n  if (options.builder) {\n    // Validate builder name\n    if (!VALID_BUILDERS.includes(options.builder)) {\n      throw new Error(\n        `Invalid nitro builder \"${options.builder}\". Valid builders are: ${VALID_BUILDERS.join(\", \")}.`\n      );\n    }\n    // Check if the builder package is installed (rolldown is a direct dep)\n    const pkg = options.builder;\n    if (pkg !== \"rolldown\" && !isPkgInstalled(pkg, options.rootDir)) {\n      const shouldInstall = await consola.prompt(\n        `Nitro builder package \\`${pkg}\\` is not installed. Would you like to install it?`,\n        { type: \"confirm\", default: true, cancel: \"null\" }\n      );\n      if (!shouldInstall) {\n        throw new Error(\n          `Nitro builder package \"${options.builder}\" is not installed. Please install it in your project dependencies.`\n        );\n      }\n      await installPkg(pkg, options.rootDir);\n    }\n    return;\n  }\n\n  // Auto-detect: check for vite.config with nitro() plugin\n  if (isPkgInstalled(\"vite\", options.rootDir) && hasNitroViteConfig(options)) {\n    options.builder = \"vite\";\n    return;\n  }\n\n  // Default to rolldown (direct dependency of nitro)\n  options.builder = \"rolldown\";\n}\n\nconst _require = createRequire(import.meta.url);\n\nfunction isPkgInstalled(pkg: string, root: string) {\n  try {\n    _require.resolve(pkg, { paths: [root] });\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nasync function installPkg(pkg: string, root: string) {\n  const { addDevDependency } = await import(\"nypm\");\n  return addDevDependency(pkg, { cwd: root });\n}\n\nfunction hasNitroViteConfig(options: NitroOptions): boolean {\n  const configExts = [\".ts\", \".mts\", \".js\", \".mjs\"];\n  for (const ext of configExts) {\n    const configPath = resolve(options.rootDir, `vite.config${ext}`);\n    if (existsSync(configPath)) {\n      try {\n        const content = readFileSync(configPath, \"utf8\");\n        if (content.includes(\"nitro(\")) {\n          return true;\n        }\n      } catch {}\n    }\n  }\n  return false;\n}\n"
  },
  {
    "path": "src/config/resolvers/compatibility.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\nimport { resolveCompatibilityDatesFromEnv } from \"compatx\";\n\nexport async function resolveCompatibilityOptions(options: NitroOptions) {\n  options.compatibilityDate = resolveCompatibilityDatesFromEnv(options.compatibilityDate);\n}\n"
  },
  {
    "path": "src/config/resolvers/database.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\n\nexport async function resolveDatabaseOptions(options: NitroOptions) {\n  if (options.experimental.database && options.imports) {\n    options.imports.presets ??= [];\n    options.imports.presets.push({\n      from: \"nitro/database\",\n      imports: [\"useDatabase\"],\n    });\n    if (options.dev && !options.database && !options.devDatabase) {\n      options.devDatabase = {\n        default: {\n          connector: \"sqlite\",\n          options: {\n            cwd: options.rootDir,\n          },\n        },\n      };\n    } else if (options.node && !options.database) {\n      options.database = {\n        default: {\n          connector: \"sqlite\",\n          options: {},\n        },\n      };\n    }\n  }\n}\n"
  },
  {
    "path": "src/config/resolvers/error.ts",
    "content": "import { runtimeDir } from \"nitro/meta\";\nimport type { NitroOptions } from \"nitro/types\";\nimport { join } from \"pathe\";\nimport { resolveNitroPath } from \"../../utils/fs.ts\";\n\nexport async function resolveErrorOptions(options: NitroOptions) {\n  if (!options.errorHandler) {\n    options.errorHandler = [];\n  } else if (!Array.isArray(options.errorHandler)) {\n    options.errorHandler = [options.errorHandler];\n  }\n\n  options.errorHandler = options.errorHandler.map((h) => resolveNitroPath(h, options));\n\n  // Always add the default error handler as the last one\n  options.errorHandler.push(join(runtimeDir, `internal/error/${options.dev ? \"dev\" : \"prod\"}`));\n}\n"
  },
  {
    "path": "src/config/resolvers/export-conditions.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\n\nexport async function resolveExportConditionsOptions(options: NitroOptions) {\n  options.exportConditions = _resolveExportConditions(options.exportConditions || [], {\n    dev: options.dev,\n    node: options.node,\n    wasm: options.wasm !== false,\n  });\n}\n\nfunction _resolveExportConditions(\n  userConditions: string[],\n  opts: { dev: boolean; node: boolean; wasm?: boolean }\n) {\n  const conditions: string[] = [...userConditions.filter((c) => !c.startsWith(\"!\"))];\n\n  conditions.push(opts.dev ? \"development\" : \"production\");\n\n  if (opts.wasm) {\n    conditions.push(\"wasm\", \"unwasm\");\n  }\n\n  if (opts.node) {\n    conditions.push(\"node\");\n  }\n\n  const negated = new Set(userConditions.filter((c) => c.startsWith(\"!\")).map((c) => c.slice(1)));\n\n  return [...new Set(conditions)].filter((c) => !negated.has(c));\n}\n"
  },
  {
    "path": "src/config/resolvers/imports.ts",
    "content": "import escapeRE from \"escape-string-regexp\";\nimport type { NitroOptions } from \"nitro/types\";\nimport { join } from \"pathe\";\n\nexport async function resolveImportsOptions(options: NitroOptions) {\n  // Skip loader entirely if imports disabled\n  if (options.imports === false) {\n    return;\n  }\n\n  options.imports.presets ??= [];\n\n  // Auto imports from utils dirs\n  options.imports.dirs ??= [];\n  options.imports.dirs.push(...options.scanDirs.map((dir) => join(dir, \"utils/**/*\")));\n\n  // Normalize exclude\n  if (Array.isArray(options.imports.exclude) && options.imports.exclude.length === 0) {\n    // Exclude .git and buildDir by default\n    options.imports.exclude.push(/[/\\\\]\\.git[/\\\\]/);\n    options.imports.exclude.push(options.buildDir);\n\n    // Exclude all node modules that are not a scanDir\n    const scanDirsInNodeModules = options.scanDirs\n      .map((dir) => dir.match(/(?<=\\/)node_modules\\/(.+)$/)?.[1])\n      .filter(Boolean) as string[];\n    options.imports.exclude.push(\n      scanDirsInNodeModules.length > 0\n        ? new RegExp(\n            `node_modules\\\\/(?!${scanDirsInNodeModules.map((dir) => escapeRE(dir)).join(\"|\")})`\n          )\n        : /[/\\\\]node_modules[/\\\\]/\n    );\n  }\n}\n"
  },
  {
    "path": "src/config/resolvers/open-api.ts",
    "content": "import { runtimeDir } from \"nitro/meta\";\nimport type { NitroOptions } from \"nitro/types\";\nimport { join } from \"pathe\";\n\nexport async function resolveOpenAPIOptions(options: NitroOptions) {\n  // Check if the experimental.openAPI option is enabled\n  if (!options.experimental.openAPI) {\n    return;\n  }\n\n  // Only enable for dev and (opt-in) production\n  if (!options.dev && !options.openAPI?.production) {\n    return;\n  }\n\n  const shouldPrerender = !options.dev && options.openAPI?.production === \"prerender\";\n\n  const handlersEnv = shouldPrerender ? \"prerender\" : \"\";\n\n  const prerenderRoutes: string[] = [];\n\n  // Add openapi json route\n  const jsonRoute = options.openAPI?.route || \"/_openapi.json\";\n  prerenderRoutes.push(jsonRoute);\n  options.handlers.push({\n    route: jsonRoute,\n    env: handlersEnv,\n    handler: join(runtimeDir, \"internal/routes/openapi\"),\n  });\n\n  // Scalar UI\n  if (options.openAPI?.ui?.scalar !== false) {\n    const scalarRoute = options.openAPI?.ui?.scalar?.route || \"/_scalar\";\n    prerenderRoutes.push(scalarRoute);\n    options.handlers.push({\n      route: options.openAPI?.ui?.scalar?.route || \"/_scalar\",\n      env: handlersEnv,\n      handler: join(runtimeDir, \"internal/routes/scalar\"),\n    });\n  }\n\n  // Swagger UI\n  if (options.openAPI?.ui?.swagger !== false) {\n    const swaggerRoute = options.openAPI?.ui?.swagger?.route || \"/_swagger\";\n    prerenderRoutes.push(swaggerRoute);\n    options.handlers.push({\n      route: swaggerRoute,\n      env: handlersEnv,\n      handler: join(runtimeDir, \"internal/routes/swagger\"),\n    });\n  }\n\n  // Prerender\n  if (shouldPrerender) {\n    options.prerender ??= {} as any;\n    options.prerender.routes ??= [];\n    options.prerender.routes.push(...prerenderRoutes);\n  }\n}\n"
  },
  {
    "path": "src/config/resolvers/paths.ts",
    "content": "import { prettyPath, resolveNitroPath } from \"../../utils/fs.ts\";\nimport { runtimeDir } from \"nitro/meta\";\nimport type { NitroOptions, NitroConfig } from \"nitro/types\";\nimport { join, resolve } from \"pathe\";\nimport { findWorkspaceDir } from \"pkg-types\";\nimport { NitroDefaults } from \"../defaults.ts\";\nimport { resolveModulePath } from \"exsolve\";\nimport consola from \"consola\";\n\nconst RESOLVE_EXTENSIONS = [\".ts\", \".js\", \".mts\", \".mjs\", \".tsx\", \".jsx\"];\n\nexport async function resolvePathOptions(options: NitroOptions) {\n  options.rootDir = resolve(options.rootDir || \".\") + \"/\";\n  options.buildDir = resolve(options.rootDir, options.buildDir || \".\") + \"/\";\n  options.workspaceDir ||=\n    (await findWorkspaceDir(options.rootDir).catch(() => options.rootDir)) + \"/\";\n\n  if (options.srcDir) {\n    if (options.serverDir === undefined) {\n      options.serverDir = options.srcDir;\n    }\n    consola.warn(`\"srcDir\" option is deprecated. Please use \"serverDir\" instead.`);\n  }\n\n  if (options.serverDir !== false) {\n    if ((options as any).serverDir === true) {\n      options.serverDir = \"server\";\n    }\n    options.serverDir = resolve(options.rootDir, options.serverDir || \".\") + \"/\";\n  }\n\n  options.alias ??= {};\n\n  // Resolve possibly template paths\n  if (!options.static && !options.entry) {\n    throw new Error(`Nitro entry is missing! Is \"${options.preset}\" preset correct?`);\n  }\n  if (options.entry) {\n    options.entry = resolveNitroPath(options.entry, options);\n  }\n\n  options.output.dir =\n    resolveNitroPath(options.output.dir || NitroDefaults.output!.dir!, options, options.rootDir) +\n    \"/\";\n  options.output.publicDir =\n    resolveNitroPath(\n      options.output.publicDir || NitroDefaults.output!.publicDir!,\n      options,\n      options.rootDir\n    ) + \"/\";\n  options.output.serverDir =\n    resolveNitroPath(\n      options.output.serverDir || NitroDefaults.output!.serverDir!,\n      options,\n      options.rootDir\n    ) + \"/\";\n\n  // Resolve plugin paths\n  options.plugins = options.plugins.map((p) => resolveNitroPath(p, options));\n\n  // Resolve scanDirs\n  if (options.serverDir) {\n    options.scanDirs.unshift(options.serverDir);\n  }\n  options.scanDirs = options.scanDirs.map((dir) => resolve(options.rootDir, dir));\n  options.scanDirs = [...new Set(options.scanDirs.map((dir) => dir + \"/\"))];\n\n  // Resolve handler and route paths\n  options.handlers = options.handlers.map((h) => {\n    return {\n      ...h,\n      handler: resolveNitroPath(h.handler, options),\n    };\n  });\n  options.routes = Object.fromEntries(\n    Object.entries(options.routes).map(([route, h]) => {\n      if (typeof h === \"string\") {\n        h = { handler: h };\n      }\n      h.handler = resolveNitroPath(h.handler, options);\n      return [route, h];\n    })\n  );\n\n  // Server entry\n  if (options.serverEntry !== false) {\n    if (typeof options?.serverEntry === \"string\") {\n      options.serverEntry = { handler: options.serverEntry };\n    }\n    if (options.serverEntry?.handler) {\n      options.serverEntry.handler = resolveNitroPath(options.serverEntry.handler, options);\n    } else {\n      const detected = resolveModulePath(\"./server\", {\n        try: true,\n        from: options.rootDir,\n        extensions: RESOLVE_EXTENSIONS.flatMap((ext) => [ext, `.node${ext}`]),\n      });\n      if (detected) {\n        options.serverEntry ??= { handler: \"\" };\n        options.serverEntry.handler = detected;\n        consola.info(`Detected \\`${prettyPath(detected)}\\` as server entry.`);\n      }\n    }\n    if (options.serverEntry?.handler && !options.serverEntry?.format) {\n      const isNode = /\\.(node)\\.\\w+$/.test(options.serverEntry.handler);\n      options.serverEntry.format = isNode ? \"node\" : \"web\";\n    }\n  }\n\n  if ((options as NitroConfig).renderer === false) {\n    // Skip (auto) resolve renderer,\n    // and reset it to meet \"NitroOptions\" requirements\n    options.renderer = undefined;\n  } else {\n    // Resolve renderer handler\n    if (options.renderer?.handler) {\n      options.renderer.handler = resolveModulePath(\n        resolveNitroPath(options.renderer?.handler, options),\n        {\n          from: [options.rootDir, ...options.scanDirs],\n          extensions: RESOLVE_EXTENSIONS,\n        }\n      );\n    }\n\n    // Resolve renderer template\n    if (options.renderer?.template) {\n      options.renderer.template = resolveModulePath(\n        resolveNitroPath(options.renderer?.template, options),\n        {\n          from: [options.rootDir, ...options.scanDirs],\n          extensions: [\".html\"],\n        }\n      )!;\n    } else if (!options.renderer?.handler) {\n      const defaultIndex = resolveModulePath(\"./index.html\", {\n        from: [options.rootDir, ...options.scanDirs],\n        extensions: [\".html\"],\n        try: true,\n      });\n      if (defaultIndex) {\n        options.renderer ??= {};\n        options.renderer.template = defaultIndex;\n        consola.info(`Using \\`${prettyPath(defaultIndex)}\\` as renderer template.`);\n      }\n    }\n\n    // Default renderer handler if template is set\n    if (options.renderer?.template && !options.renderer?.handler) {\n      options.renderer ??= {};\n      options.renderer.handler = join(\n        runtimeDir,\n        \"internal/routes/renderer-template\" + (options.dev ? \".dev\" : \"\")\n      );\n    }\n  }\n}\n"
  },
  {
    "path": "src/config/resolvers/route-rules.ts",
    "content": "import type { NitroConfig, NitroOptions, NitroRouteConfig, NitroRouteRules } from \"nitro/types\";\nimport { withLeadingSlash } from \"ufo\";\n\nexport async function resolveRouteRulesOptions(options: NitroOptions) {\n  options.routeRules = normalizeRouteRules(options);\n}\n\nexport function normalizeRouteRules(config: NitroConfig): Record<string, NitroRouteRules> {\n  const normalizedRules: Record<string, NitroRouteRules> = {};\n  for (let path in config.routeRules) {\n    const routeConfig = config.routeRules[path] as NitroRouteConfig;\n    path = withLeadingSlash(path);\n    const routeRules: NitroRouteRules = {\n      ...routeConfig,\n      redirect: undefined,\n      proxy: undefined,\n    };\n    // Redirect\n    if (routeConfig.redirect) {\n      routeRules.redirect = {\n        // @ts-ignore\n        to: \"/\",\n        status: 307,\n        ...(typeof routeConfig.redirect === \"string\"\n          ? { to: routeConfig.redirect }\n          : routeConfig.redirect),\n      };\n      if (path.endsWith(\"/**\")) {\n        // Internal flag\n        (routeRules.redirect as any)._redirectStripBase = path.slice(0, -3);\n      }\n    }\n    // Proxy\n    if (routeConfig.proxy) {\n      routeRules.proxy =\n        typeof routeConfig.proxy === \"string\" ? { to: routeConfig.proxy } : routeConfig.proxy;\n      if (path.endsWith(\"/**\")) {\n        // Internal flag\n        (routeRules.proxy as any)._proxyStripBase = path.slice(0, -3);\n      }\n    }\n    // CORS\n    if (routeConfig.cors) {\n      routeRules.headers = {\n        \"access-control-allow-origin\": \"*\",\n        \"access-control-allow-methods\": \"*\",\n        \"access-control-allow-headers\": \"*\",\n        \"access-control-max-age\": \"0\",\n        ...routeRules.headers,\n      };\n    }\n    // Cache: swr\n    if (routeConfig.swr) {\n      routeRules.cache = routeRules.cache || {};\n      routeRules.cache.swr = true;\n      if (typeof routeConfig.swr === \"number\") {\n        routeRules.cache.maxAge = routeConfig.swr;\n      }\n    }\n    // Cache: false\n    if (routeConfig.cache === false) {\n      routeRules.cache = false;\n    }\n    normalizedRules[path] = routeRules;\n  }\n  return normalizedRules;\n}\n"
  },
  {
    "path": "src/config/resolvers/runtime-config.ts",
    "content": "import { defu } from \"defu\";\n\nimport type { NitroConfig, NitroOptions, NitroRuntimeConfig } from \"nitro/types\";\n\nexport async function resolveRuntimeConfigOptions(options: NitroOptions) {\n  options.runtimeConfig = normalizeRuntimeConfig(options);\n}\n\nexport function normalizeRuntimeConfig(config: NitroConfig) {\n  provideFallbackValues(config.runtimeConfig || {});\n  const runtimeConfig: NitroRuntimeConfig = defu(\n    config.runtimeConfig as NitroRuntimeConfig,\n    {\n      app: {\n        baseURL: config.baseURL,\n      },\n      nitro: {\n        envExpansion: config.experimental?.envExpansion,\n        openAPI: config.openAPI,\n      },\n    } as NitroRuntimeConfig\n  );\n  runtimeConfig.nitro ??= {};\n  runtimeConfig.nitro.routeRules = config.routeRules;\n  checkSerializableRuntimeConfig(runtimeConfig);\n  return runtimeConfig as NitroRuntimeConfig;\n}\n\nfunction provideFallbackValues(obj: Record<string, any>) {\n  for (const key in obj) {\n    if (obj[key] === undefined || obj[key] === null) {\n      obj[key] = \"\";\n    } else if (typeof obj[key] === \"object\") {\n      provideFallbackValues(obj[key]);\n    }\n  }\n}\n\nfunction checkSerializableRuntimeConfig(obj: any, path: string[] = []) {\n  if (isPrimitiveValue(obj)) {\n    return;\n  }\n\n  for (const key in obj) {\n    const value = obj[key];\n    if (value === null || value === undefined || isPrimitiveValue(value)) {\n      continue;\n    }\n\n    if (Array.isArray(value)) {\n      for (const [index, item] of value.entries())\n        checkSerializableRuntimeConfig(item, [...path, `${key}[${index}]`]);\n    } else if (\n      typeof value === \"object\" &&\n      value.constructor === Object &&\n      (!value.constructor?.name || value.constructor.name === \"Object\")\n    ) {\n      checkSerializableRuntimeConfig(value, [...path, key]);\n    } else {\n      console.warn(\n        `Runtime config option \\`${[...path, key].join(\".\")}\\` may not be able to be serialized.`\n      );\n    }\n  }\n}\n\nfunction isPrimitiveValue(value: any) {\n  return typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\";\n}\n"
  },
  {
    "path": "src/config/resolvers/storage.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\n\nexport async function resolveStorageOptions(options: NitroOptions) {\n  //\n}\n"
  },
  {
    "path": "src/config/resolvers/tsconfig.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\nimport type { TSConfig } from \"pkg-types\";\nimport { join, resolve } from \"pathe\";\nimport * as tsco from \"tsconfck\";\n\nexport async function resolveTsconfig(options: NitroOptions) {\n  const root = resolve(options.rootDir || \".\") + \"/\";\n  if (!options.typescript.tsConfig) {\n    options.typescript.tsConfig = await loadTsconfig(root);\n  }\n}\n\nasync function loadTsconfig(root: string): Promise<TSConfig> {\n  const opts: tsco.TSConfckParseOptions = {\n    root,\n    cache: ((loadTsconfig as any)[\"__cache\"] ??= new tsco.TSConfckCache()),\n    ignoreNodeModules: true,\n  };\n  const tsConfigPath = join(root, \"tsconfig.json\");\n  const parsed = await tsco.parse(tsConfigPath, opts).catch(() => undefined);\n  if (!parsed) return {} as TSConfig;\n  const { tsconfig, tsconfigFile } = parsed;\n  tsconfig.compilerOptions ??= {};\n  if (!tsconfig.compilerOptions.baseUrl) {\n    tsconfig.compilerOptions.baseUrl = resolve(tsconfigFile, \"..\");\n  }\n  return tsconfig;\n}\n"
  },
  {
    "path": "src/config/resolvers/unenv.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\nimport type { Preset } from \"unenv\";\n\nexport const common: Preset = {\n  meta: {\n    name: \"nitro-common\",\n    url: import.meta.url,\n  },\n  alias: {\n    \"buffer/\": \"node:buffer\",\n    \"buffer/index\": \"node:buffer\",\n    \"buffer/index.js\": \"node:buffer\",\n    \"string_decoder/\": \"node:string_decoder\",\n    \"process/\": \"node:process\",\n  },\n};\n\nexport const nodeless: Preset = {\n  meta: {\n    name: \"nitro-nodeless\",\n    url: import.meta.url,\n  },\n  inject: {\n    global: \"unenv/polyfill/globalthis\",\n    process: \"node:process\",\n    Buffer: [\"node:buffer\", \"Buffer\"],\n    clearImmediate: [\"node:timers\", \"clearImmediate\"],\n    setImmediate: [\"node:timers\", \"setImmediate\"],\n    performance: \"unenv/polyfill/performance\",\n    PerformanceObserver: [\"node:perf_hooks\", \"PerformanceObserver\"],\n    BroadcastChannel: [\"node:worker_threads\", \"BroadcastChannel\"],\n  },\n  polyfill: [\n    \"unenv/polyfill/globalthis-global\",\n    \"unenv/polyfill/process\",\n    \"unenv/polyfill/buffer\",\n    \"unenv/polyfill/timers\",\n  ],\n};\n\nexport async function resolveUnenv(options: NitroOptions) {\n  options.unenv ??= [];\n  if (!Array.isArray(options.unenv)) {\n    options.unenv = [options.unenv];\n  }\n  options.unenv = options.unenv.filter(Boolean);\n  if (!options.node) {\n    options.unenv.unshift(nodeless);\n  }\n  options.unenv.unshift(common);\n}\n"
  },
  {
    "path": "src/config/resolvers/url.ts",
    "content": "import type { NitroOptions } from \"nitro/types\";\nimport { withLeadingSlash, withTrailingSlash } from \"ufo\";\n\nexport async function resolveURLOptions(options: NitroOptions) {\n  options.baseURL = withLeadingSlash(withTrailingSlash(options.baseURL));\n}\n"
  },
  {
    "path": "src/config/update.ts",
    "content": "import consola from \"consola\";\nimport type { Nitro, NitroDynamicConfig } from \"nitro/types\";\nimport { normalizeRouteRules } from \"./resolvers/route-rules.ts\";\nimport { normalizeRuntimeConfig } from \"./resolvers/runtime-config.ts\";\n\nexport async function updateNitroConfig(nitro: Nitro, config: NitroDynamicConfig) {\n  nitro.options.routeRules = normalizeRouteRules(config.routeRules ? config : nitro.options);\n  nitro.options.runtimeConfig = normalizeRuntimeConfig(\n    config.runtimeConfig ? config : nitro.options\n  );\n  await nitro.hooks.callHook(\"rollup:reload\");\n  consola.success(\"Nitro config hot reloaded!\");\n}\n"
  },
  {
    "path": "src/dev/app.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { H3Event, HTTPHandler } from \"h3\";\nimport { createProxyServer, type ProxyServerOptions } from \"httpxy\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { H3, toEventHandler, serveStatic, fromNodeHandler, HTTPError } from \"h3\";\nimport { joinURL } from \"ufo\";\nimport mime from \"mime\";\nimport { join, resolve, extname } from \"pathe\";\nimport { stat } from \"node:fs/promises\";\nimport { createReadStream } from \"node:fs\";\nimport { createGzip, createBrotliCompress } from \"node:zlib\";\nimport { createVFSHandler } from \"./vfs.ts\";\n\nimport devErrorHandler, {\n  defaultHandler as devErrorHandlerInternal,\n  loadStackTrace,\n} from \"../runtime/internal/error/dev.ts\";\n\nexport class NitroDevApp {\n  nitro: Nitro;\n  fetch: (req: Request) => Response | Promise<Response>;\n\n  constructor(nitro: Nitro, catchAllHandler?: HTTPHandler) {\n    this.nitro = nitro;\n    const app = this.#createApp(catchAllHandler);\n    this.fetch = app.fetch.bind(app);\n  }\n\n  #createApp(catchAllHandler?: HTTPHandler) {\n    // Init h3 app\n    const app = new H3({\n      debug: true,\n      onError: async (error, event) => {\n        const errorHandler = this.nitro.options.devErrorHandler || devErrorHandler;\n        await loadStackTrace(error).catch(() => {});\n        return errorHandler(error, event, {\n          defaultHandler: devErrorHandlerInternal,\n        });\n      },\n    });\n\n    // Dev-only handlers\n    for (const h of this.nitro.options.devHandlers) {\n      const handler = toEventHandler(h.handler);\n      if (!handler) {\n        this.nitro.logger.warn(\"Invalid dev handler:\", h);\n        continue;\n      }\n      if (h.middleware || !h.route) {\n        // Middleware\n        if (h.route) {\n          app.use(h.route, handler, { method: h.method });\n        } else {\n          app.use(handler, { method: h.method });\n        }\n      } else {\n        // Route\n        app.on(h.method || \"\", h.route, handler, { meta: h.meta as any });\n      }\n    }\n\n    // Debugging endpoint to view vfs\n    app.get(\"/_vfs/**\", createVFSHandler(this.nitro));\n\n    // Serve asset dirs\n    for (const asset of this.nitro.options.publicAssets) {\n      const assetBase = joinURL(this.nitro.options.baseURL, asset.baseURL || \"/\");\n      app.use(joinURL(assetBase, \"**\"), (event) =>\n        serveStaticDir(event, {\n          dir: asset.dir,\n          base: assetBase,\n          fallthrough: asset.fallthrough,\n        })\n      );\n    }\n\n    // User defined dev proxy\n    const routes = Object.keys(this.nitro.options.devProxy).sort().reverse();\n    for (const route of routes) {\n      let opts = this.nitro.options.devProxy[route];\n      if (typeof opts === \"string\") {\n        opts = { target: opts };\n      }\n      const proxy = createHTTPProxy(opts);\n      app.all(route, proxy.handleEvent);\n    }\n\n    // Main handler\n    if (catchAllHandler) {\n      app.all(\"/**\", catchAllHandler);\n    }\n\n    return app;\n  }\n}\n\n// TODO: upstream to h3/node\nfunction serveStaticDir(\n  event: H3Event,\n  opts: { dir: string; base: string; fallthrough?: boolean }\n) {\n  const dir = resolve(opts.dir) + \"/\";\n  const r = (id: string) => {\n    if (!id.startsWith(opts.base) || !extname(id)) return;\n    const resolved = join(dir, id.slice(opts.base.length));\n    if (resolved.startsWith(dir)) {\n      return resolved;\n    }\n  };\n  return serveStatic(event, {\n    fallthrough: opts.fallthrough,\n    getMeta: async (id) => {\n      const path = r(id);\n      if (!path) return;\n      const s = await stat(path).catch(() => null);\n      if (!s?.isFile()) return;\n      const ext = extname(path);\n      return {\n        size: s.size,\n        mtime: s.mtime,\n        type: mime.getType(ext) || \"application/octet-stream\",\n      };\n    },\n    getContents(id) {\n      const path = r(id);\n      if (!path) return;\n      const stream = createReadStream(path);\n      const acceptEncoding = event.req.headers.get(\"accept-encoding\") || \"\";\n      if (acceptEncoding.includes(\"br\")) {\n        event.res.headers.set(\"Content-Encoding\", \"br\");\n        event.res.headers.delete(\"Content-Length\");\n        event.res.headers.set(\"Vary\", \"Accept-Encoding\");\n        return stream.pipe(createBrotliCompress());\n      } else if (acceptEncoding.includes(\"gzip\")) {\n        event.res.headers.set(\"Content-Encoding\", \"gzip\");\n        event.res.headers.delete(\"Content-Length\");\n        event.res.headers.set(\"Vary\", \"Accept-Encoding\");\n        return stream.pipe(createGzip());\n      }\n      return stream as any;\n    },\n  });\n}\n\nfunction createHTTPProxy(defaults: ProxyServerOptions = {}) {\n  const proxy = createProxyServer({ xfwd: true, ...defaults });\n  return {\n    proxy,\n    async handleEvent(event: H3Event, opts?: ProxyServerOptions) {\n      try {\n        return await fromNodeHandler((req, res) => {\n          return proxy.web(req as IncomingMessage, res as ServerResponse, opts);\n        })(event);\n      } catch (error: any) {\n        event.res.headers.set(\"refresh\", \"3\");\n        throw new HTTPError({\n          status: 503,\n          message: \"Dev server is unavailable.\",\n          cause: error,\n        });\n      }\n    },\n  };\n}\n"
  },
  {
    "path": "src/dev/server.ts",
    "content": "import type { IncomingMessage } from \"node:http\";\nimport type { Socket } from \"node:net\";\nimport type { FSWatcher } from \"chokidar\";\nimport type { ServerOptions, Server } from \"srvx\";\nimport type { EnvRunnerData, RunnerMessageListener, RunnerRPCHooks } from \"env-runner\";\nimport type { RunnerName } from \"env-runner\";\nimport { RunnerManager, loadRunner } from \"env-runner\";\nimport type { Nitro } from \"nitro/types\";\n\nimport { HTTPError } from \"h3\";\n\nimport consola from \"consola\";\nimport { resolve } from \"pathe\";\nimport { watch } from \"chokidar\";\nimport { serve } from \"srvx/node\";\nimport { debounce } from \"perfect-debounce\";\nimport { isTest, isCI } from \"std-env\";\nimport { NitroDevApp } from \"./app.ts\";\nimport { writeDevBuildInfo } from \"../build/info.ts\";\n\nexport function createDevServer(nitro: Nitro): NitroDevServer {\n  return new NitroDevServer(nitro);\n}\n\nexport class NitroDevServer extends NitroDevApp implements RunnerRPCHooks {\n  #entry: string;\n  #workerData: EnvRunnerData = {};\n  #listeners: Server[] = [];\n  #watcher?: FSWatcher;\n  #manager: RunnerManager;\n  #workerIdCtr: number = 0;\n  #workerError?: unknown;\n  #workerRetries: number = 0;\n  #building?: boolean = true; // Assume initial build will start soon\n  #buildError?: unknown;\n  #reloadPromise?: Promise<void>;\n\n  constructor(nitro: Nitro) {\n    super(nitro, async (event) => {\n      if (this.#building) {\n        await this.#waitForBuild();\n      }\n      if (this.#reloadPromise) {\n        await this.#reloadPromise;\n      }\n      if (this.#buildError) {\n        return this.#generateError();\n      }\n      const response = await this.#manager.fetch(event.req as Request);\n      if (response.status === 503 && !this.#manager.ready) {\n        return this.#generateError();\n      }\n      return response;\n    });\n\n    // Bind all methods to `this`\n    for (const key of Object.getOwnPropertyNames(NitroDevServer.prototype)) {\n      const value = (this as any)[key];\n      if (typeof value === \"function\" && key !== \"constructor\") {\n        (this as any)[key] = value.bind(this);\n      }\n    }\n\n    // Attach to Nitro.fetch\n    nitro.fetch = this.fetch.bind(this);\n\n    this.#entry = resolve(nitro.options.output.dir, nitro.options.output.serverDir, \"index.mjs\");\n\n    this.#manager = new RunnerManager();\n    this.#manager.onReady(async (_runner, addr) => {\n      this.#workerRetries = 0;\n      writeDevBuildInfo(this.nitro, addr).catch((error) => {\n        this.nitro.logger.warn(\n          `Failed to write dev build info: ${error instanceof Error ? error.message : String(error)}`\n        );\n      });\n    });\n    this.#manager.onClose((_runner, cause) => {\n      this.#workerError = cause;\n      if (this.#workerRetries++ < 3) {\n        this.nitro.logger.info(\"Restarting dev worker...\", cause ? `Cause: ${cause}` : \"\");\n        this.reload();\n      } else {\n        this.nitro.logger.error(\n          \"Dev worker failed after 3 retries.\",\n          cause ? `Last cause: ${cause}` : \"\"\n        );\n      }\n    });\n\n    nitro.hooks.hook(\"close\", () => this.close());\n\n    nitro.hooks.hook(\"dev:start\", () => {\n      this.#building = true;\n      this.#buildError = undefined;\n    });\n\n    nitro.hooks.hook(\"dev:reload\", (payload) => {\n      this.#buildError = undefined;\n      this.#building = false;\n      if (payload?.entry) {\n        this.#entry = payload.entry;\n      }\n      if (payload?.workerData) {\n        this.#workerData = payload.workerData;\n      }\n      this.reload();\n    });\n\n    nitro.hooks.hook(\"dev:error\", (cause: unknown) => {\n      this.#buildError = cause;\n      this.#building = false;\n    });\n\n    const devWatch = nitro.options.devServer.watch;\n    if (devWatch && devWatch.length > 0) {\n      const debouncedReload = debounce(() => this.reload());\n      this.#watcher = watch(devWatch, nitro.options.watchOptions);\n      this.#watcher.on(\"add\", debouncedReload).on(\"change\", debouncedReload);\n    }\n  }\n\n  // #region Public Methods\n\n  async upgrade(req: IncomingMessage, socket: Socket, head: any) {\n    if (!this.#manager.upgrade) {\n      throw new HTTPError({\n        status: 501,\n        statusText: \"Worker does not support upgrades.\",\n      });\n    }\n    return this.#manager.upgrade({ node: { req, socket, head } });\n  }\n\n  listen(opts?: Partial<Omit<ServerOptions, \"fetch\">>): Server {\n    const server = serve({\n      ...opts,\n      fetch: this.fetch,\n      gracefulShutdown: false,\n    });\n    this.#listeners.push(server);\n    if (server.node?.server) {\n      server.node.server.on(\"upgrade\", (req, sock, head) => this.upgrade(req, sock, head));\n    }\n    return server;\n  }\n\n  async close() {\n    await Promise.all(\n      [\n        Promise.all(this.#listeners.map((l) => l.close())).then(() => {\n          this.#listeners = [];\n        }),\n        this.#manager.close(),\n        Promise.resolve(this.#watcher?.close()).then(() => {\n          this.#watcher = undefined;\n        }),\n      ].map((p) =>\n        p.catch((error) => {\n          consola.error(error);\n        })\n      )\n    );\n  }\n\n  reload() {\n    const nextReload = (this.#reloadPromise ?? Promise.resolve())\n      .catch(() => {})\n      .then(() => this.#reload());\n    this.#reloadPromise = nextReload.finally(() => {\n      if (this.#reloadPromise === nextReload) {\n        this.#reloadPromise = undefined;\n      }\n    });\n  }\n\n  async #reload() {\n    const runnerName =\n      this.nitro.options.devServer.runner || process.env.NITRO_DEV_RUNNER || \"node-worker\";\n    const runner = await loadRunner(runnerName as RunnerName, {\n      name: `Nitro_${this.#workerIdCtr++}`,\n      data: { entry: this.#entry, ...this.#workerData },\n    });\n    await this.#manager.reload(runner);\n  }\n\n  sendMessage(message: unknown) {\n    this.#manager.sendMessage(message);\n  }\n\n  onMessage(listener: RunnerMessageListener) {\n    this.#manager.onMessage(listener);\n  }\n\n  offMessage(listener: RunnerMessageListener) {\n    this.#manager.offMessage(listener);\n  }\n\n  // #endregion\n\n  // #region Private Methods\n\n  async #waitForBuild() {\n    const timeout = isTest || isCI ? 60_000 : 6000;\n    await this.#manager.waitForReady(timeout);\n  }\n\n  #generateError() {\n    const error: any = this.#buildError || this.#workerError;\n    if (error) {\n      try {\n        error.unhandled = false;\n        let id = error.id || error.path;\n        if (id) {\n          const cause = (error as { errors?: any[] }).errors?.[0];\n          const loc = error.location || error.loc || cause?.location || cause?.loc;\n          if (loc) {\n            id += `:${loc.line}:${loc.column}`;\n          }\n          error.stack = (error.stack || \"\").replace(/(^\\s*at\\s+.+)/m, `    at ${id}\\n$1`);\n        }\n      } catch {\n        // ignore\n      }\n      return new HTTPError(error);\n    }\n\n    return new Response(\n      JSON.stringify(\n        {\n          error: \"Dev server is unavailable.\",\n          hint: \"Please reload the page and check the console for errors if the issue persists.\",\n        },\n        null,\n        2\n      ),\n      {\n        status: 503,\n        statusText: \"Dev server is unavailable\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n          \"Cache-Control\": \"no-store\",\n          Refresh: \"3\",\n        },\n      }\n    );\n  }\n\n  // #endregion\n}\n"
  },
  {
    "path": "src/dev/vfs.ts",
    "content": "import { HTTPError, defineHandler, getRequestIP } from \"h3\";\nimport type { Nitro } from \"nitro/types\";\n\nexport function createVFSHandler(nitro: Nitro) {\n  return defineHandler(async (event) => {\n    const { socket } = event.runtime?.node?.req || {};\n\n    // prettier-ignore\n    const isUnixSocket =\n      // No network addresses\n      (!socket?.remoteAddress && !socket?.localAddress) &&\n      // Empty address object\n      Object.keys(socket?.address?.() || {}).length === 0 &&\n      // Socket is readable/writable but has no port info\n      socket?.readable && socket?.writable && !socket?.remotePort;\n\n    const ip = getRequestIP(event, { xForwardedFor: isUnixSocket });\n\n    const isLocalRequest = ip && /^::1$|^127\\.\\d+\\.\\d+\\.\\d+$/.test(ip);\n    if (!isLocalRequest) {\n      throw new HTTPError({\n        statusText: `Forbidden IP: \"${ip || \"?\"}\"`,\n        status: 403,\n      });\n    }\n\n    const url = event.context.params?._ || \"\";\n    const isJson =\n      url.endsWith(\".json\") || event.req.headers.get(\"accept\")?.includes(\"application/json\");\n    const id = decodeURIComponent(url.replace(/^(\\.json)?\\/?/, \"\") || \"\");\n\n    if (id && !nitro.vfs.has(id)) {\n      throw new HTTPError({ message: \"File not found\", status: 404 });\n    }\n\n    const content = id ? await nitro.vfs.get(id)?.render() : undefined;\n\n    if (isJson) {\n      return {\n        rootDir: nitro.options.rootDir,\n        entries: [...nitro.vfs.keys()].map((id) => ({\n          id,\n          path: \"/_vfs.json/\" + encodeURIComponent(id),\n        })),\n        current: id\n          ? {\n              id,\n              content,\n            }\n          : null,\n      };\n    }\n\n    const directories: Record<string, any> = { [nitro.options.rootDir]: {} };\n    const fpaths = [...nitro.vfs.keys()];\n\n    for (const item of fpaths) {\n      const segments = item.replace(nitro.options.rootDir, \"\").split(\"/\").filter(Boolean);\n      let currentDir = item.startsWith(nitro.options.rootDir)\n        ? directories[nitro.options.rootDir]\n        : directories;\n\n      for (const segment of segments) {\n        if (!currentDir[segment]) {\n          currentDir[segment] = {};\n        }\n\n        currentDir = currentDir[segment];\n      }\n    }\n\n    const generateHTML = (directory: Record<string, any>, path: string[] = []): string =>\n      Object.entries(directory)\n        .map(([fname, value = {}]) => {\n          const subpath = [...path, fname];\n          const key = subpath.join(\"/\");\n          const encodedUrl = encodeURIComponent(key);\n\n          const linkClass =\n            url === `/${encodedUrl}` ? \"bg-gray-700 text-white\" : \"hover:bg-gray-800 text-gray-200\";\n\n          return Object.keys(value).length === 0\n            ? `\n            <li class=\"flex flex-nowrap\">\n              <a href=\"/_vfs/${encodedUrl}\" class=\"w-full text-sm px-2 py-1 border-b border-gray-10 ${linkClass}\">\n                ${fname}\n              </a>\n            </li>\n            `\n            : `\n            <li>\n              <details ${url.startsWith(`/${encodedUrl}`) ? \"open\" : \"\"}>\n                <summary class=\"w-full text-sm px-2 py-1 border-b border-gray-10 hover:bg-gray-800 text-gray-200\">\n                  ${fname}\n                </summary>\n                <ul class=\"ml-4\">\n                  ${generateHTML(value, subpath)}\n                </ul>\n              </details>\n            </li>\n            `;\n        })\n        .join(\"\");\n\n    const rootDirectory = directories[nitro.options.rootDir];\n    delete directories[nitro.options.rootDir];\n    const items = generateHTML(rootDirectory, [nitro.options.rootDir]) + generateHTML(directories);\n\n    const files = `\n      <div class=\"h-full overflow-auto border-r border-gray:10\">\n        <p class=\"text-white text-bold text-center py-1 opacity-50\">Virtual Files</p>\n        <ul class=\"flex flex-col\">${items}</ul>\n      </div>\n      `;\n\n    const file = id\n      ? editorTemplate({\n          readOnly: true,\n          language: id.endsWith(\"html\") ? \"html\" : \"javascript\",\n          theme: \"vs-dark\",\n          value: content,\n          wordWrap: \"wordWrapColumn\",\n          wordWrapColumn: 80,\n        })\n      : `\n        <div class=\"w-full h-full flex opacity-50\">\n          <h1 class=\"text-white m-auto\">Select a virtual file to inspect</h1>\n        </div>\n      `;\n\n    event.res.headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n    return /* html */ `\n<!doctype html>\n<html>\n<head>\n  <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/@unocss/reset/tailwind.min.css\" />\n  <link rel=\"stylesheet\" data-name=\"vs/editor/editor.main\" href=\"${vsUrl}/editor/editor.main.min.css\">\n  <script src=\"https://cdn.jsdelivr.net/npm/@unocss/runtime\"></script>\n  <style>\n    html {\n      background: #1E1E1E;\n      color: white;\n    }\n    [un-cloak] {\n      display: none;\n    }\n  </style>\n</head>\n<body class=\"bg-[#1E1E1E]\">\n  <div un-cloak class=\"h-screen grid grid-cols-[300px_1fr]\">\n    ${files}\n    ${file}\n  </div>\n</body>\n</html>`;\n  });\n}\n\nconst monacoVersion = \"0.30.0\";\nconst monacoUrl = `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/${monacoVersion}/min`;\nconst vsUrl = `${monacoUrl}/vs`;\n\nconst editorTemplate = (options: Record<string, any>) => `\n<div id=\"editor\" class=\"min-h-screen w-full h-full\"></div>\n<script src=\"${vsUrl}/loader.min.js\"></script>\n<script>\n  require.config({ paths: { vs: '${vsUrl}' } })\n\n  const proxy = URL.createObjectURL(new Blob([\\`\n    self.MonacoEnvironment = { baseUrl: '${monacoUrl}' }\n    importScripts('${vsUrl}/base/worker/workerMain.min.js')\n  \\`], { type: 'text/javascript' }))\n  window.MonacoEnvironment = { getWorkerUrl: () => proxy }\n\n  setTimeout(() => {\n    require(['vs/editor/editor.main'], function () {\n      monaco.editor.create(document.getElementById('editor'), ${JSON.stringify(options)})\n    })\n  }, 0);\n</script>\n`;\n"
  },
  {
    "path": "src/global.ts",
    "content": "import type { Nitro } from \"nitro/types\";\n\nconst nitroInstances: Nitro[] = ((globalThis as any).__nitro_instances__ ||= []);\n\nconst globalKey = \"__nitro_builder__\";\n\ndeclare global {\n  var __nitro_builder__: {\n    fetch: (req: Request) => Promise<Response>;\n  };\n}\n\nexport function registerNitroInstance(nitro: Nitro) {\n  if (nitroInstances.includes(nitro)) {\n    return;\n  }\n  globalInit();\n  nitroInstances.unshift(nitro);\n  nitro.hooks.hookOnce(\"close\", () => {\n    nitroInstances.splice(nitroInstances.indexOf(nitro), 1);\n    if (nitroInstances.length === 0) {\n      delete (globalThis as any)[globalKey];\n    }\n  });\n}\n\nfunction globalInit() {\n  if (globalThis[globalKey]) {\n    return;\n  }\n  globalThis[globalKey] = {\n    async fetch(req) {\n      for (let r = 0; r < 10 && nitroInstances.length === 0; r++) {\n        await new Promise((resolve) => setTimeout(resolve, 300));\n      }\n      const nitro = nitroInstances[0];\n      if (!nitro) {\n        throw new Error(\"No Nitro instance is running.\");\n      }\n      return nitro.fetch(req);\n    },\n  };\n}\n"
  },
  {
    "path": "src/module.ts",
    "content": "import type { Nitro, NitroModule, NitroModuleInput } from \"nitro/types\";\nimport { resolveModuleURL } from \"exsolve\";\n\nexport async function installModules(nitro: Nitro) {\n  const _modules = [...(nitro.options.modules || [])];\n  const modules = await Promise.all(_modules.map((mod) => _resolveNitroModule(mod, nitro.options)));\n  const _installedURLs = new Set<string>();\n  for (const mod of modules) {\n    if (mod._url) {\n      if (_installedURLs.has(mod._url)) {\n        continue;\n      }\n      _installedURLs.add(mod._url);\n    }\n    await mod.setup(nitro);\n  }\n}\n\nasync function _resolveNitroModule(\n  mod: NitroModuleInput,\n  nitroOptions: Nitro[\"options\"]\n): Promise<NitroModule & { _url?: string }> {\n  let _url: string | undefined;\n\n  if (typeof mod === \"string\") {\n    _url = resolveModuleURL(mod, {\n      from: [nitroOptions.rootDir],\n      extensions: [\".mjs\", \".cjs\", \".js\", \".mts\", \".cts\", \".ts\"],\n    });\n    mod = (await import(_url).then((m: any) => m.default || m)) as NitroModule;\n  }\n\n  if (typeof mod === \"function\") {\n    mod = { setup: mod };\n  }\n\n  if (\"nitro\" in mod) {\n    mod = mod.nitro;\n  }\n\n  if (!mod.setup) {\n    throw new Error(\"Invalid Nitro module: missing setup() function.\");\n  }\n\n  return {\n    _url,\n    ...mod,\n  };\n}\n"
  },
  {
    "path": "src/nitro.ts",
    "content": "import { consola } from \"consola\";\nimport { Hookable, createDebugger } from \"hookable\";\nimport type { LoadConfigOptions, Nitro, NitroConfig, NitroDynamicConfig } from \"nitro/types\";\nimport { loadOptions } from \"./config/loader.ts\";\nimport { updateNitroConfig } from \"./config/update.ts\";\nimport { installModules } from \"./module.ts\";\nimport { scanAndSyncOptions, scanHandlers } from \"./scan.ts\";\nimport { initNitroRouting } from \"./routing.ts\";\nimport { registerNitroInstance } from \"./global.ts\";\n\nexport async function createNitro(\n  config: NitroConfig = {},\n  opts: LoadConfigOptions = {}\n): Promise<Nitro> {\n  // Resolve options\n  const options = await loadOptions(config, opts);\n\n  // Create nitro context\n  const nitro: Nitro = {\n    options,\n    hooks: new Hookable(),\n    vfs: new Map(),\n    routing: {} as any,\n    logger: consola.withTag(\"nitro\"),\n    scannedHandlers: [],\n    fetch: () => {\n      throw new Error(\"no dev server attached!\");\n    },\n    close: () => Promise.resolve(nitro.hooks.callHook(\"close\")),\n    async updateConfig(config: NitroDynamicConfig) {\n      updateNitroConfig(nitro, config);\n    },\n  };\n\n  // Global setup\n  registerNitroInstance(nitro);\n\n  // Init routers\n  initNitroRouting(nitro);\n\n  // Scan dirs (plugins, tasks, modules) and sync options\n  // TODO: Make it side-effect free to allow proper watching\n  await scanAndSyncOptions(nitro);\n\n  // Debug\n  if (nitro.options.debug) {\n    createDebugger(nitro.hooks, { tag: \"nitro\" });\n  }\n\n  // Logger\n  if (nitro.options.logLevel !== undefined) {\n    nitro.logger.level = nitro.options.logLevel;\n  }\n\n  // Hooks\n  nitro.hooks.addHooks(nitro.options.hooks);\n\n  // Scan and install modules\n  await installModules(nitro);\n\n  // Auto imports\n  if (nitro.options.imports) {\n    // Create unimport instance\n    const { createUnimport } = await import(\"unimport\");\n    nitro.unimport = createUnimport(nitro.options.imports);\n    await nitro.unimport.init();\n    // Support for importing from '#imports'\n    nitro.options.virtual[\"#imports\"] = () => nitro.unimport?.toExports() || \"\";\n    // Backward compatibility\n    nitro.options.virtual[\"#nitro\"] = 'export * from \"#imports\"';\n  }\n\n  // Ensure initial handlers are populated\n  await scanHandlers(nitro);\n\n  // Sync routers\n  nitro.routing.sync();\n\n  return nitro;\n}\n"
  },
  {
    "path": "src/prerender/prerender.ts",
    "content": "import { pathToFileURL } from \"node:url\";\nimport { defu } from \"defu\";\nimport mime from \"mime\";\nimport { writeFile } from \"../utils/fs.ts\";\nimport type { Nitro, NitroRouteRules, PrerenderRoute, PublicAssetDir } from \"nitro/types\";\nimport { join, relative, resolve } from \"pathe\";\nimport { createRouter, addRoute, findAllRoutes } from \"rou3\";\nimport { joinURL, withBase, withoutBase, withTrailingSlash } from \"ufo\";\nimport { build } from \"../build/build.ts\";\nimport { createNitro } from \"../nitro.ts\";\nimport { compressPublicAssets } from \"../utils/compress.ts\";\nimport { runParallel } from \"../utils/parallel.ts\";\nimport { extractLinks, formatPrerenderRoute, matchesIgnorePattern } from \"./utils.ts\";\nimport { scanUnprefixedPublicAssets } from \"../build/assets.ts\";\nimport { toRequest } from \"h3\";\n\nconst JsonSigRx = /^\\s*[\"[{]|^\\s*-?\\d{1,16}(\\.\\d{1,17})?([Ee][+-]?\\d+)?\\s*$/; // From unjs/destr\n\n// const linkParents = new Map<string, Set<string>>();\n\nexport async function prerender(nitro: Nitro) {\n  if (nitro.options.noPublicDir) {\n    nitro.logger.warn(\"Skipping prerender since `noPublicDir` option is enabled.\");\n    return;\n  }\n\n  // Initial list of routes to prerender\n  const routes = new Set(nitro.options.prerender.routes);\n\n  // Extend with static prerender route rules\n  const prerenderRulePaths = Object.entries(nitro.options.routeRules)\n    .filter(([path, options]) => options.prerender && !path.includes(\"*\"))\n    .map((e) => e[0]);\n  for (const route of prerenderRulePaths) {\n    routes.add(route);\n  }\n\n  // Allow extending prerender routes\n  await nitro.hooks.callHook(\"prerender:routes\", routes);\n\n  // Skip if no prerender routes specified\n  if (routes.size === 0) {\n    // Crawl / at least if no routes are specified\n    if (nitro.options.prerender.crawlLinks) {\n      routes.add(\"/\");\n    } else {\n      return;\n    }\n  }\n\n  // Build with prerender preset\n  nitro.logger.info(\"Initializing prerenderer\");\n  nitro._prerenderedRoutes = [];\n  nitro._prerenderMeta = nitro._prerenderMeta || {};\n  const prerendererConfig = {\n    ...nitro.options._config,\n    static: false,\n    rootDir: nitro.options.rootDir,\n    logLevel: 0,\n    preset: \"nitro-prerender\",\n    builder: nitro.options.builder === \"vite\" ? \"rolldown\" : nitro.options.builder,\n  };\n  await nitro.hooks.callHook(\"prerender:config\", prerendererConfig);\n  const nitroRenderer = await createNitro(prerendererConfig);\n  const prerenderStartTime = Date.now();\n  await nitro.hooks.callHook(\"prerender:init\", nitroRenderer);\n\n  // Set path to preview prerendered routes relative to the \"host\" nitro preset\n  let path = relative(nitro.options.output.dir, nitro.options.output.publicDir);\n  if (!path.startsWith(\".\")) {\n    path = `./${path}`;\n  }\n  nitroRenderer.options.commands.preview = `npx serve ${path}`;\n  nitroRenderer.options.output.dir = nitro.options.output.dir;\n\n  await build(nitroRenderer);\n\n  // Import renderer entry\n  const serverFilename =\n    typeof nitroRenderer.options.rollupConfig?.output?.entryFileNames === \"string\"\n      ? nitroRenderer.options.rollupConfig.output.entryFileNames\n      : \"index.mjs\";\n  const serverEntrypoint = resolve(nitroRenderer.options.output.serverDir, serverFilename);\n  const entryURL = pathToFileURL(serverEntrypoint).href;\n  const prerenderer = (await import(entryURL).then((m: any) => m.default)) as {\n    close: () => Promise<void>;\n    fetch: (req: Request) => Promise<Response>;\n  };\n\n  // Create route rule matcher\n  const routeRules = createRouter<NitroRouteRules>();\n  for (const [route, rules] of Object.entries(nitro.options.routeRules)) {\n    addRoute(routeRules, undefined, route, rules);\n  }\n\n  const _getRouteRules = (path: string) =>\n    defu(\n      {},\n      ...findAllRoutes(routeRules, undefined, path)\n        .map((r) => r.data)\n        .reverse()\n    ) as NitroRouteRules;\n\n  // Start prerendering\n  const generatedRoutes = new Set();\n  const failedRoutes = new Set<PrerenderRoute>();\n  const skippedRoutes = new Set();\n  const displayedLengthWarns = new Set();\n\n  const publicAssetBases: string[] = nitro.options.publicAssets\n    .filter(\n      (a): a is PublicAssetDir & { baseURL: string } =>\n        !!a.baseURL && a.baseURL !== \"/\" && !a.fallthrough\n    )\n    .map((a) => withTrailingSlash(a.baseURL));\n\n  const scannedPublicAssets = nitro.options.prerender.ignoreUnprefixedPublicAssets\n    ? new Set(await scanUnprefixedPublicAssets(nitro))\n    : new Set<string>();\n\n  const canPrerender = (route = \"/\") => {\n    // Skip if route is already generated or skipped\n    if (generatedRoutes.has(route) || skippedRoutes.has(route)) {\n      return false;\n    }\n\n    // Check for explicitly ignored routes\n    if (nitro.options.prerender.ignore) {\n      for (const pattern of nitro.options.prerender.ignore) {\n        if (matchesIgnorePattern(route, pattern)) {\n          return false;\n        }\n      }\n    }\n\n    if (publicAssetBases.some((base) => route.startsWith(base))) {\n      return false;\n    }\n\n    if (scannedPublicAssets.has(route)) {\n      return false;\n    }\n\n    // Check for route rules explicitly disabling prerender\n    if (_getRouteRules(route).prerender === false) {\n      return false;\n    }\n\n    return true;\n  };\n\n  const canWriteToDisk = (route: PrerenderRoute) => {\n    // Cannot write routes with query or containing ..\n    if (route.route.includes(\"?\") || route.route.includes(\"..\")) {\n      return false;\n    }\n\n    // Ensure length is not too long for filesystem\n    // https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits\n    const FS_MAX_SEGMENT = 255;\n    // 1024 is the max path length on APFS (undocumented)\n    const FS_MAX_PATH = 1024;\n    const FS_MAX_PATH_PUBLIC_HTML = FS_MAX_PATH - (nitro.options.output.publicDir.length + 10);\n\n    if (\n      (route.route.length >= FS_MAX_PATH_PUBLIC_HTML ||\n        route.route.split(\"/\").some((s) => s.length > FS_MAX_SEGMENT)) &&\n      !displayedLengthWarns.has(route)\n    ) {\n      displayedLengthWarns.add(route);\n      const _route = route.route.slice(0, 60) + \"...\";\n      if (route.route.length >= FS_MAX_PATH_PUBLIC_HTML) {\n        nitro.logger.warn(\n          `Prerendering long route \"${_route}\" (${route.route.length}) can cause filesystem issues since it exceeds ${FS_MAX_PATH_PUBLIC_HTML}-character limit when writing to \\`${nitro.options.output.publicDir}\\`.`\n        );\n      } else {\n        nitro.logger.warn(\n          `Skipping prerender of the route \"${_route}\" since it exceeds the ${FS_MAX_SEGMENT}-character limit in one of the path segments and can cause filesystem issues.`\n        );\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  const generateRoute = async (route: string) => {\n    const start = Date.now();\n\n    // Ensure route is decoded to start with\n    route = decodeURI(route);\n\n    // Check if we should render route\n    if (!canPrerender(route)) {\n      skippedRoutes.add(route);\n      return;\n    }\n    generatedRoutes.add(route);\n\n    // Create result object\n    const _route: PrerenderRoute = { route };\n\n    // Fetch the route\n    const encodedRoute = encodeURI(route);\n\n    const req = toRequest(withBase(encodedRoute, nitro.options.baseURL), {\n      headers: [[\"x-nitro-prerender\", encodedRoute]],\n      // TODO\n      // retry: nitro.options.prerender.retry,\n      // retryDelay: nitro.options.prerender.retryDelay,\n    });\n    const res = await prerenderer.fetch(req);\n    // Data will be removed as soon as written to the disk\n    let dataBuff: Buffer | undefined = Buffer.from(await res.arrayBuffer());\n\n    Object.defineProperty(_route, \"contents\", {\n      get: () => {\n        return dataBuff ? dataBuff.toString(\"utf8\") : undefined;\n      },\n      set(value: string) {\n        // Only set if we didn't consume the buffer yet\n        if (dataBuff) {\n          dataBuff = Buffer.from(value);\n        }\n      },\n    });\n    Object.defineProperty(_route, \"data\", {\n      get: () => {\n        return dataBuff ? dataBuff.buffer : undefined;\n      },\n      set(value: string) {\n        // Only set if we didn't consume the buffer yet\n        if (dataBuff) {\n          dataBuff = Buffer.from(value);\n        }\n      },\n    });\n\n    // https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections\n    const redirectCodes = [301, 302, 303, 304, 307, 308];\n    if (![200, ...redirectCodes].includes(res.status)) {\n      _route.error = new Error(`[${res.status}] ${res.statusText}`) as any;\n      // @ts-expect-error (typed as readonly)\n      _route.error!.status = res.status;\n      // @ts-expect-error (typed as readonly)\n      _route.error!.statusText = res.statusText;\n    }\n\n    // Measure actual time taken for generating route\n    _route.generateTimeMS = Date.now() - start;\n\n    // Guess route type and populate fileName\n    const contentType = res.headers.get(\"content-type\") || \"\";\n    const isImplicitHTML =\n      !route.endsWith(\".html\") &&\n      contentType.includes(\"html\") &&\n      !JsonSigRx.test(dataBuff!.subarray(0, 32).toString(\"utf8\"));\n    const routeWithIndex = route.endsWith(\"/\") ? route + \"index\" : route;\n    const htmlPath =\n      route.endsWith(\"/\") || nitro.options.prerender.autoSubfolderIndex\n        ? joinURL(route, \"index.html\")\n        : route + \".html\";\n    _route.fileName = withoutBase(\n      isImplicitHTML ? htmlPath : routeWithIndex,\n      nitro.options.baseURL\n    );\n    // Allow overriding content-type in `prerender:generate` hook\n    const inferredContentType = mime.getType(_route.fileName) || \"text/plain\";\n    _route.contentType = contentType || inferredContentType;\n\n    // Allow hooking before generate\n    await nitro.hooks.callHook(\"prerender:generate\", _route, nitro);\n    if (_route.contentType !== inferredContentType) {\n      nitro._prerenderMeta![_route.fileName] ||= {};\n      nitro._prerenderMeta![_route.fileName].contentType = _route.contentType;\n    }\n\n    // After hook to allow ignoring in `prerender:generate` hook\n    if (_route.error) {\n      failedRoutes.add(_route);\n    }\n\n    // Check if route is skipped or has errors\n    if (_route.skip || _route.error) {\n      await nitro.hooks.callHook(\"prerender:route\", _route);\n      nitro.logger.log(formatPrerenderRoute(_route));\n      dataBuff = undefined; // Free memory\n      return _route;\n    }\n\n    // Write to the disk\n    const filePath = join(nitro.options.output.publicDir, _route.fileName);\n    if (canWriteToDisk(_route) && filePath.startsWith(nitro.options.output.publicDir)) {\n      await writeFile(filePath, dataBuff!);\n      nitro._prerenderedRoutes!.push(_route);\n    } else {\n      _route.skip = true;\n    }\n\n    // Crawl route links\n    if (!_route.error && (isImplicitHTML || route.endsWith(\".html\"))) {\n      const extractedLinks = await extractLinks(\n        dataBuff!.toString(\"utf8\"),\n        route,\n        res,\n        nitro.options.prerender.crawlLinks ?? false\n      );\n      for (const _link of extractedLinks) {\n        if (canPrerender(_link)) {\n          routes.add(_link);\n        }\n      }\n    }\n\n    await nitro.hooks.callHook(\"prerender:route\", _route);\n    nitro.logger.log(formatPrerenderRoute(_route));\n\n    dataBuff = undefined; // Free memory\n    return _route;\n  };\n\n  nitro.logger.info(\n    nitro.options.prerender.crawlLinks\n      ? `Prerendering ${routes.size} initial routes with crawler`\n      : `Prerendering ${routes.size} routes`\n  );\n\n  await runParallel(routes, generateRoute, {\n    concurrency: nitro.options.prerender.concurrency || 1,\n    interval: nitro.options.prerender.interval,\n  });\n\n  await prerenderer.close();\n\n  await nitro.hooks.callHook(\"prerender:done\", {\n    prerenderedRoutes: nitro._prerenderedRoutes,\n    failedRoutes: [...failedRoutes],\n  });\n\n  if (nitro.options.prerender.failOnError && failedRoutes.size > 0) {\n    nitro.logger.log(\"\\nErrors prerendering:\");\n    for (const route of failedRoutes) {\n      // const parents = linkParents.get(route.route);\n      // const parentsText = parents?.size\n      //   ? `\\n${[...parents.values()]\n      //       .map((link) => colors.gray(`  │ └── Linked from ${link}`))\n      //       .join(\"\\n\")}`\n      //   : \"\";\n      nitro.logger.log(formatPrerenderRoute(route));\n    }\n    nitro.logger.log(\"\");\n    throw new Error(\"Exiting due to prerender errors.\");\n  }\n\n  const prerenderTimeInMs = Date.now() - prerenderStartTime;\n  nitro.logger.info(\n    `Prerendered ${nitro._prerenderedRoutes.length} routes in ${prerenderTimeInMs / 1000} seconds`\n  );\n\n  if (nitro.options.compressPublicAssets) {\n    await compressPublicAssets(nitro);\n  }\n}\n"
  },
  {
    "path": "src/prerender/utils.ts",
    "content": "import { colors } from \"consola/utils\";\nimport type { PrerenderRoute } from \"nitro/types\";\nimport { parseURL } from \"ufo\";\nimport { parse as parseHTML, walk } from \"ultrahtml\";\n\nconst allowedExtensions = new Set([\"\", \".json\"]);\n\nconst linkParents = new Map<string, Set<string>>();\n\nconst HTML_ENTITIES = {\n  \"&lt;\": \"<\",\n  \"&gt;\": \">\",\n  \"&amp;\": \"&\",\n  \"&apos;\": \"'\",\n  \"&quot;\": '\"',\n} as Record<string, string>;\n\nfunction escapeHtml(text: string) {\n  return text.replace(/&(lt|gt|amp|apos|quot);/g, (ch) => HTML_ENTITIES[ch] || ch);\n}\n\nexport async function extractLinks(html: string, from: string, res: Response, crawlLinks: boolean) {\n  const links: string[] = [];\n  const _links: string[] = [];\n\n  // Extract from any <TAG href=\"\"> to crawl\n  if (crawlLinks) {\n    await walk(parseHTML(html), (node) => {\n      if (!node.attributes?.href) {\n        return;\n      }\n\n      const link = escapeHtml(node.attributes.href);\n      if (!decodeURIComponent(link).startsWith(\"#\") && allowedExtensions.has(getExtension(link))) {\n        _links.push(link);\n      }\n    });\n  }\n\n  // Extract from x-nitro-prerender headers\n  const header = res.headers.get(\"x-nitro-prerender\") || \"\";\n  _links.push(...header.split(\",\").map((i) => decodeURIComponent(i.trim())));\n\n  for (const link of _links.filter(Boolean)) {\n    const _link = parseURL(link);\n    if (_link.protocol || _link.host) {\n      continue;\n    }\n    if (!_link.pathname.startsWith(\"/\")) {\n      const fromURL = new URL(from, \"http://localhost\");\n      _link.pathname = new URL(_link.pathname, fromURL).pathname;\n    }\n    links.push(_link.pathname + _link.search);\n  }\n  for (const link of links) {\n    const _parents = linkParents.get(link);\n    if (_parents) {\n      _parents.add(from);\n    } else {\n      linkParents.set(link, new Set([from]));\n    }\n  }\n  return links;\n}\n\nconst EXT_REGEX = /\\.[\\da-z]+$/;\n\nfunction getExtension(link: string): string {\n  const pathname = parseURL(link).pathname;\n  return (pathname.match(EXT_REGEX) || [])[0] || \"\";\n}\n\nexport function formatPrerenderRoute(route: PrerenderRoute) {\n  let str = `  ├─ ${route.route} (${route.generateTimeMS}ms)`;\n\n  if (route.error) {\n    const parents = linkParents.get(route.route);\n    const errorColor = colors[route.error.status === 404 ? \"yellow\" : \"red\"];\n    const errorLead = parents?.size ? \"├──\" : \"└──\";\n    str += `\\n  │ ${errorLead} ${errorColor(route.error.message || \"unknown error\")}`;\n\n    if (parents?.size) {\n      str += `\\n${[...parents.values()].map((link) => `  │ └── Linked from ${link}`).join(\"\\n\")}`;\n    }\n  }\n\n  if (route.skip) {\n    str += colors.gray(\" (skipped)\");\n  }\n\n  return colors.gray(str);\n}\n\n// prettier-ignore\ntype IgnorePattern =\n  | string\n  | RegExp\n  | ((path: string) => undefined | null | boolean);\nexport function matchesIgnorePattern(path: string, pattern: IgnorePattern) {\n  if (typeof pattern === \"string\") {\n    // TODO: support rou3 patterns\n    return path.startsWith(pattern as string);\n  }\n\n  if (typeof pattern === \"function\") {\n    return pattern(path) === true;\n  }\n\n  if (pattern instanceof RegExp) {\n    return pattern.test(path);\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/presets/_all.gen.ts",
    "content": "// Auto-generated using gen-presets script\n\nimport _nitro from \"./_nitro/preset.ts\";\nimport _static from \"./_static/preset.ts\";\nimport _alwaysdata from \"./alwaysdata/preset.ts\";\nimport _awsAmplify from \"./aws-amplify/preset.ts\";\nimport _awsLambda from \"./aws-lambda/preset.ts\";\nimport _azure from \"./azure/preset.ts\";\nimport _bun from \"./bun/preset.ts\";\nimport _cleavr from \"./cleavr/preset.ts\";\nimport _cloudflare from \"./cloudflare/preset.ts\";\nimport _deno from \"./deno/preset.ts\";\nimport _digitalocean from \"./digitalocean/preset.ts\";\nimport _firebase from \"./firebase/preset.ts\";\nimport _flightcontrol from \"./flightcontrol/preset.ts\";\nimport _genezio from \"./genezio/preset.ts\";\nimport _heroku from \"./heroku/preset.ts\";\nimport _iis from \"./iis/preset.ts\";\nimport _koyeb from \"./koyeb/preset.ts\";\nimport _netlify from \"./netlify/preset.ts\";\nimport _node from \"./node/preset.ts\";\nimport _platformSh from \"./platform.sh/preset.ts\";\nimport _renderCom from \"./render.com/preset.ts\";\nimport _standard from \"./standard/preset.ts\";\nimport _stormkit from \"./stormkit/preset.ts\";\nimport _vercel from \"./vercel/preset.ts\";\nimport _winterjs from \"./winterjs/preset.ts\";\nimport _zeabur from \"./zeabur/preset.ts\";\nimport _zephyr from \"./zephyr/preset.ts\";\nimport _zerops from \"./zerops/preset.ts\";\n\nexport default [\n  ..._nitro,\n  ..._static,\n  ..._alwaysdata,\n  ..._awsAmplify,\n  ..._awsLambda,\n  ..._azure,\n  ..._bun,\n  ..._cleavr,\n  ..._cloudflare,\n  ..._deno,\n  ..._digitalocean,\n  ..._firebase,\n  ..._flightcontrol,\n  ..._genezio,\n  ..._heroku,\n  ..._iis,\n  ..._koyeb,\n  ..._netlify,\n  ..._node,\n  ..._platformSh,\n  ..._renderCom,\n  ..._standard,\n  ..._stormkit,\n  ..._vercel,\n  ..._winterjs,\n  ..._zeabur,\n  ..._zephyr,\n  ..._zerops,\n] as const;\n"
  },
  {
    "path": "src/presets/_nitro/base-worker.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst baseWorker = defineNitroPreset(\n  {\n    entry: null as any, // Abstract\n    node: false,\n    minify: true,\n    noExternals: true,\n    rollupConfig: {\n      output: {\n        format: \"iife\",\n        generatedCode: {\n          symbols: true,\n        },\n      },\n    },\n    inlineDynamicImports: true, // iffe does not support code-splitting\n  },\n  {\n    name: \"base-worker\" as const,\n  }\n);\n\nexport default [baseWorker] as const;\n"
  },
  {
    "path": "src/presets/_nitro/nitro-dev.ts",
    "content": "import { runtimeDir } from \"nitro/meta\";\nimport { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { join } from \"pathe\";\n\nconst nitroDev = defineNitroPreset(\n  {\n    entry: \"./_nitro/runtime/nitro-dev\",\n    output: {\n      dir: \"{{ buildDir }}/dev\",\n      serverDir: \"{{ buildDir }}/dev\",\n      publicDir: \"{{ buildDir }}/dev\",\n    },\n    handlers: [\n      {\n        route: \"/_nitro/tasks/**\",\n        lazy: true,\n        handler: join(runtimeDir, \"internal/routes/dev-tasks\"),\n      },\n    ],\n    externals: { noTrace: true },\n    serveStatic: true,\n    inlineDynamicImports: true, // externals plugin limitation\n    sourcemap: true,\n  },\n  {\n    name: \"nitro-dev\" as const,\n    dev: true,\n  }\n);\n\nexport default [nitroDev] as const;\n"
  },
  {
    "path": "src/presets/_nitro/nitro-prerender.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst nitroPrerender = defineNitroPreset(\n  {\n    entry: \"./_nitro/runtime/nitro-prerenderer\",\n    serveStatic: true,\n    output: {\n      serverDir: \"{{ buildDir }}/prerender\",\n    },\n    externals: { noTrace: true },\n  },\n  {\n    name: \"nitro-prerender\" as const,\n  }\n);\n\nexport default [nitroPrerender] as const;\n"
  },
  {
    "path": "src/presets/_nitro/preset.ts",
    "content": "import worker from \"./base-worker.ts\";\nimport dev from \"./nitro-dev.ts\";\nimport prerender from \"./nitro-prerender.ts\";\n\nexport default [...worker, ...dev, ...prerender] as const;\n"
  },
  {
    "path": "src/presets/_nitro/runtime/nitro-dev.ts",
    "content": "import \"#nitro/virtual/polyfills\";\n\nimport { useNitroApp, useNitroHooks } from \"nitro/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\nimport { trapUnhandledErrors } from \"#nitro/runtime/error/hooks\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nimport type { AppEntry } from \"env-runner\";\n\nconst nitroApp = useNitroApp();\nconst nitroHooks = useNitroHooks();\n\ntrapUnhandledErrors();\n\n// Scheduled tasks\nif (import.meta._tasks) {\n  startScheduleRunner({});\n}\n\nconst ws = import.meta._websocket\n  ? await import(\"crossws/adapters/node\").then((m) =>\n      (m.default || m)({ resolve: resolveWebsocketHooks })\n    )\n  : undefined;\n\nexport default {\n  fetch: nitroApp.fetch,\n  upgrade: ws\n    ? (context: { node: { req: any; socket: any; head: any } }) => {\n        ws.handleUpgrade(context.node.req, context.node.socket, context.node.head);\n      }\n    : undefined,\n  ipc: {\n    onClose: () => nitroHooks.callHook(\"close\"),\n  },\n} satisfies AppEntry;\n"
  },
  {
    "path": "src/presets/_nitro/runtime/nitro-prerenderer.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport consola from \"consola\";\nimport { HTTPError } from \"h3\";\nimport { useNitroApp, useNitroHooks } from \"nitro/app\";\n\nconst nitroApp = useNitroApp();\nconst nitroHooks = useNitroHooks();\n\nexport default {\n  fetch: nitroApp.fetch,\n  close: () => nitroHooks.callHook(\"close\"),\n};\n\nnitroHooks.hook(\"error\", (error, context) => {\n  if (\n    !(error as HTTPError).unhandled &&\n    (error as HTTPError).status >= 500 &&\n    context.event?.req?.headers instanceof Headers &&\n    context.event.req.headers.get(\"x-nitro-prerender\")\n  ) {\n    consola.error(\n      `[prerender error]`,\n      `[${context.event.req.method}]`,\n      `[${context.event.req.url}]`,\n      error\n    );\n  }\n});\n"
  },
  {
    "path": "src/presets/_nitro/runtime/service-worker.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport { isPublicAssetURL } from \"#nitro/virtual/public-assets\";\nimport type { ServerRequest } from \"srvx\";\n\nconst nitroApp = useNitroApp();\n\n// @ts-expect-error\naddEventListener(\"fetch\", (event: FetchEvent) => {\n  const url = new URL(event.request.url);\n  if (isPublicAssetURL(url.pathname) || url.pathname.includes(\"/_server/\")) {\n    return;\n  }\n\n  // srvx compatibility\n  const req = event.request as unknown as ServerRequest;\n  req.runtime ??= { name: \"service-worker\" };\n  req.runtime.serviceWorker ??= { event } as any;\n  req.waitUntil = event.waitUntil.bind(event);\n\n  event.respondWith(nitroApp.fetch(req));\n});\n\ndeclare const self: ServiceWorkerGlobalScope;\n\nself.addEventListener(\"install\", () => {\n  self.skipWaiting();\n});\n\nself.addEventListener(\"activate\", (event) => {\n  event.waitUntil(self.clients.claim());\n});\n"
  },
  {
    "path": "src/presets/_resolve.ts",
    "content": "import { resolveCompatibilityDatesFromEnv, formatCompatibilityDate } from \"compatx\";\nimport type { CompatibilityDateSpec, PlatformName } from \"compatx\";\nimport type { NitroPreset, NitroPresetMeta } from \"nitro/types\";\nimport { kebabCase } from \"scule\";\nimport { provider, runtime } from \"std-env\";\nimport type { ProviderName } from \"std-env\";\nimport allPresets from \"./_all.gen.ts\";\n\n// std-env has more specific keys for providers than compatx\nconst _stdProviderMap: Partial<Record<ProviderName, PlatformName>> = {\n  aws_amplify: \"aws\",\n  azure_static: \"azure\",\n  cloudflare_pages: \"cloudflare\",\n};\n\nexport async function resolvePreset(\n  name: string,\n  opts: {\n    static?: boolean;\n    compatibilityDate?: false | CompatibilityDateSpec;\n    dev?: boolean;\n  } = {}\n): Promise<(NitroPreset & { _meta?: NitroPresetMeta }) | undefined> {\n  if (name === \".\") {\n    return undefined; // invalid input\n  }\n\n  const _name = kebabCase(name) || provider;\n\n  const _compatDates = opts.compatibilityDate\n    ? resolveCompatibilityDatesFromEnv(opts.compatibilityDate)\n    : false;\n\n  const matches = allPresets\n    .filter((preset) => {\n      // prettier-ignore\n      const names = [preset._meta.name, preset._meta.stdName, ...(preset._meta.aliases || [])].filter(Boolean);\n      if (!names.includes(_name)) {\n        return false;\n      }\n\n      // Match dev|prod\n      if ((opts.dev && !preset._meta.dev) || (!opts.dev && preset._meta.dev)) {\n        return false;\n      }\n\n      if (_compatDates) {\n        const _date =\n          _compatDates[_stdProviderMap[preset._meta.stdName!] as PlatformName] ||\n          _compatDates[preset._meta.stdName as PlatformName] ||\n          _compatDates[preset._meta.name as PlatformName] ||\n          _compatDates.default;\n\n        if (\n          _date &&\n          preset._meta.compatibilityDate &&\n          new Date(preset._meta.compatibilityDate) > new Date(_date)\n        ) {\n          return false;\n        }\n      }\n\n      return true;\n    })\n    .sort((a, b) => {\n      const aDate = new Date(a._meta.compatibilityDate || 0);\n      const bDate = new Date(b._meta.compatibilityDate || 0);\n      return bDate > aDate ? 1 : -1;\n    });\n\n  const preset =\n    matches.find((p) => (p._meta.static || false) === (opts?.static || false)) || matches[0];\n\n  if (typeof preset === \"function\") {\n    // @ts-expect-error unreachable\n    return preset();\n  }\n\n  // Auto-detect preset\n  if (!name && !preset) {\n    if (opts?.static) {\n      return resolvePreset(\"static\", opts);\n    }\n    const runtimeMap = { deno: \"deno\", bun: \"bun\" } as Record<string, string>;\n    return resolvePreset(runtimeMap[runtime] || \"node\", opts);\n  }\n\n  if (name && !preset) {\n    // prettier-ignore\n    const options = allPresets\n      .filter((p) =>p._meta.name === name ||p._meta.stdName === name ||p._meta.aliases?.includes(name) )\n      .sort((a, b) => (a._meta.compatibilityDate || 0) > (b._meta.compatibilityDate || 0) ? 1 : -1);\n    if (options.length > 0) {\n      let msg = `Preset \"${name}\" cannot be resolved with current compatibilityDate: ${formatCompatibilityDate(_compatDates || \"\")}.\\n\\n`;\n      for (const option of options) {\n        msg += `\\n- ${option._meta.name} (requires compatibilityDate >= ${option._meta.compatibilityDate})`;\n      }\n      const err = new Error(msg);\n      Error.captureStackTrace?.(err, resolvePreset);\n      throw err;\n    }\n  }\n\n  return preset;\n}\n"
  },
  {
    "path": "src/presets/_static/preset.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { join } from \"pathe\";\n\nconst _static = defineNitroPreset(\n  {\n    static: true,\n    output: {\n      dir: \"{{ rootDir }}/.output\",\n      publicDir: \"{{ output.dir }}/public\",\n    },\n    prerender: {\n      crawlLinks: true,\n    },\n    commands: {\n      preview: \"npx serve ./public\",\n    },\n  },\n  {\n    name: \"static\" as const,\n    static: true,\n  }\n);\n\nconst githubPages = defineNitroPreset(\n  {\n    extends: \"static\",\n    commands: {\n      deploy: \"npx gh-pages --dotfiles -d ./public\",\n    },\n    prerender: {\n      routes: [\n        \"/\",\n        // https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-custom-404-page-for-your-github-pages-site\n        \"/404.html\",\n      ],\n    },\n    hooks: {\n      async compiled(nitro) {\n        await fsp.writeFile(join(nitro.options.output.publicDir, \".nojekyll\"), \"\");\n      },\n    },\n  },\n  {\n    name: \"github-pages\" as const,\n    static: true,\n  }\n);\n\nconst gitlabPages = defineNitroPreset(\n  {\n    extends: \"static\",\n    prerender: {\n      routes: [\n        \"/\",\n        // https://docs.gitlab.com/ee/user/project/pages/introduction.html#custom-error-codes-pages\n        \"/404.html\",\n      ],\n    },\n  },\n  {\n    name: \"gitlab-pages\" as const,\n    static: true,\n  }\n);\n\nexport default [_static, githubPages, gitlabPages] as const;\n"
  },
  {
    "path": "src/presets/_types.gen.ts",
    "content": "// Auto-generated using gen-presets script\n\nimport type { PresetOptions as AwsAmplifyOptions } from \"./aws-amplify/preset.ts\";\nimport type { PresetOptions as AwsLambdaOptions } from \"./aws-lambda/preset.ts\";\nimport type { PresetOptions as AzureOptions } from \"./azure/preset.ts\";\nimport type { PresetOptions as CloudflareOptions } from \"./cloudflare/preset.ts\";\nimport type { PresetOptions as FirebaseOptions } from \"./firebase/preset.ts\";\nimport type { PresetOptions as NetlifyOptions } from \"./netlify/preset.ts\";\nimport type { PresetOptions as VercelOptions } from \"./vercel/preset.ts\";\nimport type { PresetOptions as ZephyrOptions } from \"./zephyr/preset.ts\";\n\nexport interface PresetOptions {\n  awsAmplify?: AwsAmplifyOptions;\n  awsLambda?: AwsLambdaOptions;\n  azure?: AzureOptions;\n  cloudflare?: CloudflareOptions;\n  firebase?: FirebaseOptions;\n  netlify?: NetlifyOptions;\n  vercel?: VercelOptions;\n  zephyr?: ZephyrOptions;\n}\n\nexport const presetsWithConfig = [\"awsAmplify\",\"awsLambda\",\"azure\",\"cloudflare\",\"firebase\",\"netlify\",\"vercel\",\"zephyr\"] as const;\n\nexport type PresetName = \"alwaysdata\" | \"aws-amplify\" | \"aws-lambda\" | \"azure-swa\" | \"base-worker\" | \"bun\" | \"cleavr\" | \"cloudflare-dev\" | \"cloudflare-durable\" | \"cloudflare-module\" | \"cloudflare-pages\" | \"cloudflare-pages-static\" | \"deno\" | \"deno-deploy\" | \"deno-server\" | \"digital-ocean\" | \"firebase-app-hosting\" | \"flight-control\" | \"genezio\" | \"github-pages\" | \"gitlab-pages\" | \"heroku\" | \"iis-handler\" | \"iis-node\" | \"koyeb\" | \"netlify\" | \"netlify-edge\" | \"netlify-static\" | \"nitro-dev\" | \"nitro-prerender\" | \"node\" | \"node-cluster\" | \"node-middleware\" | \"node-server\" | \"platform-sh\" | \"render-com\" | \"standard\" | \"static\" | \"stormkit\" | \"vercel\" | \"vercel-static\" | \"winterjs\" | \"zeabur\" | \"zeabur-static\" | \"zephyr\" | \"zerops\" | \"zerops-static\";\n\nexport type PresetNameInput = \"alwaysdata\" | \"aws-amplify\" | \"awsAmplify\" | \"aws_amplify\" | \"aws-lambda\" | \"awsLambda\" | \"aws_lambda\" | \"azure-swa\" | \"azureSwa\" | \"azure_swa\" | \"base-worker\" | \"baseWorker\" | \"base_worker\" | \"bun\" | \"cleavr\" | \"cloudflare-dev\" | \"cloudflareDev\" | \"cloudflare_dev\" | \"cloudflare-durable\" | \"cloudflareDurable\" | \"cloudflare_durable\" | \"cloudflare-module\" | \"cloudflareModule\" | \"cloudflare_module\" | \"cloudflare-pages\" | \"cloudflarePages\" | \"cloudflare_pages\" | \"cloudflare-pages-static\" | \"cloudflarePagesStatic\" | \"cloudflare_pages_static\" | \"deno\" | \"deno-deploy\" | \"denoDeploy\" | \"deno_deploy\" | \"deno-server\" | \"denoServer\" | \"deno_server\" | \"digital-ocean\" | \"digitalOcean\" | \"digital_ocean\" | \"firebase-app-hosting\" | \"firebaseAppHosting\" | \"firebase_app_hosting\" | \"flight-control\" | \"flightControl\" | \"flight_control\" | \"genezio\" | \"github-pages\" | \"githubPages\" | \"github_pages\" | \"gitlab-pages\" | \"gitlabPages\" | \"gitlab_pages\" | \"heroku\" | \"iis-handler\" | \"iisHandler\" | \"iis_handler\" | \"iis-node\" | \"iisNode\" | \"iis_node\" | \"koyeb\" | \"netlify\" | \"netlify-edge\" | \"netlifyEdge\" | \"netlify_edge\" | \"netlify-static\" | \"netlifyStatic\" | \"netlify_static\" | \"nitro-dev\" | \"nitroDev\" | \"nitro_dev\" | \"nitro-prerender\" | \"nitroPrerender\" | \"nitro_prerender\" | \"node\" | \"node-cluster\" | \"nodeCluster\" | \"node_cluster\" | \"node-middleware\" | \"nodeMiddleware\" | \"node_middleware\" | \"node-server\" | \"nodeServer\" | \"node_server\" | \"platform-sh\" | \"platformSh\" | \"platform_sh\" | \"render-com\" | \"renderCom\" | \"render_com\" | \"standard\" | \"static\" | \"stormkit\" | \"vercel\" | \"vercel-static\" | \"vercelStatic\" | \"vercel_static\" | \"winterjs\" | \"zeabur\" | \"zeabur-static\" | \"zeaburStatic\" | \"zeabur_static\" | \"zephyr\" | \"zerops\" | \"zerops-static\" | \"zeropsStatic\" | \"zerops_static\" | (string & {});\n"
  },
  {
    "path": "src/presets/_utils/fs.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport { relative, dirname } from \"pathe\";\nimport consola from \"consola\";\nimport { colors } from \"consola/utils\";\n\nexport function prettyPath(p: string, highlight = true) {\n  p = relative(process.cwd(), p);\n  return highlight ? colors.cyan(p) : p;\n}\n\nexport async function writeFile(file: string, contents: Buffer | string, log = false) {\n  await fsp.mkdir(dirname(file), { recursive: true });\n  await fsp.writeFile(file, contents, typeof contents === \"string\" ? \"utf8\" : undefined);\n  if (log) {\n    consola.info(\"Generated\", prettyPath(file));\n  }\n}\n\nexport async function isDirectory(path: string) {\n  try {\n    return (await fsp.stat(path)).isDirectory();\n  } catch {\n    return false;\n  }\n}\n"
  },
  {
    "path": "src/presets/_utils/preset.ts",
    "content": "import type { NitroPreset, NitroPresetMeta } from \"nitro/types\";\n\nimport { presetsDir } from \"nitro/meta\";\nimport { resolve } from \"node:path\";\n\nexport function defineNitroPreset<P extends NitroPreset, M extends NitroPresetMeta>(\n  preset: P,\n  meta?: M\n): P & { _meta: NitroPresetMeta } {\n  if (typeof preset !== \"function\" && preset.entry && preset.entry.startsWith(\".\")) {\n    preset.entry = resolve(presetsDir, preset.entry);\n  }\n  return { ...preset, _meta: meta } as P & { _meta: M };\n}\n"
  },
  {
    "path": "src/presets/alwaysdata/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst alwaysdata = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n    commands: {\n      deploy: \"rsync -rRt --info=progress2 ./ [account]@ssh-[account].alwaysdata.net:www/my-app\",\n    },\n  },\n  {\n    name: \"alwaysdata\" as const,\n  }\n);\n\nexport default [alwaysdata] as const;\n"
  },
  {
    "path": "src/presets/aws-amplify/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { writeAmplifyFiles } from \"./utils.ts\";\n\nexport type { AWSAmplifyOptions as PresetOptions } from \"./types.ts\";\n\nconst awsAmplify = defineNitroPreset(\n  {\n    entry: \"./aws-amplify/runtime/aws-amplify\",\n    manifest: {\n      // https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html#amplify-console-environment-variables\n      deploymentId: process.env.AWS_JOB_ID,\n    },\n    serveStatic: true,\n    output: {\n      dir: \"{{ rootDir }}/.amplify-hosting\",\n      serverDir: \"{{ output.dir }}/compute/default\",\n      publicDir: \"{{ output.dir }}/static{{ baseURL }}\",\n    },\n    commands: {\n      preview: \"node ./compute/default/server.js\",\n    },\n    hooks: {\n      async compiled(nitro) {\n        await writeAmplifyFiles(nitro);\n      },\n    },\n  },\n  {\n    name: \"aws-amplify\" as const,\n    stdName: \"aws_amplify\",\n  }\n);\n\nexport default [awsAmplify] as const;\n"
  },
  {
    "path": "src/presets/aws-amplify/runtime/aws-amplify.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\n\nimport { Server } from \"node:http\";\nimport type { NodeHttp1Handler } from \"srvx\";\nimport { toNodeHandler } from \"srvx/node\";\n\nconst nitroApp = useNitroApp();\n\nconst server = new Server(toNodeHandler(nitroApp.fetch) as NodeHttp1Handler);\n\n// @ts-ignore\nserver.listen(3000, (err) => {\n  if (err) {\n    console.error(err);\n  } else {\n    console.log(`Listening on http://localhost:3000 (AWS Amplify Hosting)`);\n  }\n});\n"
  },
  {
    "path": "src/presets/aws-amplify/types.ts",
    "content": "export interface AmplifyComputeConfig {\n  /**\n   * The name property dictates the name of the provisioned compute resource. It is also the name\n   * of the sub-directory in the `compute` folder in the deployment bundle.\n   */\n  name: string;\n  /**\n   * The runtime property dictates the runtime of the provisioned compute resource.\n   * Values are subset of https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html\n   */\n  runtime: \"nodejs20.x\" | \"nodejs22.x\";\n\n  /**\n   * Specifies the starting file from which code will run for the given compute resource.\n   * The specified file should exist inside the given sub-directory that represents a compute resource.\n   *\n   * @example `\"entrypoint.js\"`\n   */\n  entrypoint: string;\n}\n\nexport type AmplifyRouteTarget =\n  | { kind: \"Static\"; cacheControl?: string }\n  | { kind: \"ImageOptimization\"; cacheControl?: string }\n  | {\n      kind: \"Compute\";\n      /**\n       * A string that indicates the name of the sub-directory in the given deployment bundle that\n       * contains the primitive's executable code. Valid and required only for the Compute primitive.\n       * The value here should point to one of the compute resources present in the given\n       * deployment bundle. The only supported value for this field is default.\n       */\n      src: string;\n    };\n\nexport type AmplifyRoute = {\n  /**\n   * The path defines a glob pattern that matches incoming request paths (excluding querystring).\n   * The first match in a given list of rules determines which routing rule is applied to the incoming request.\n   * Only the following wildcard characters are supported as far as pattern matching is concerned: `*` (matches 0 or more characters)\n   *\n   * _Note_: The \"/*\" pattern is called a catch-all pattern and will match all incoming requests.\n   * It is special because fallback routing is only supported for catch-all routes.\n   *\n   */\n  path: string;\n\n  /**\n   * An object that dictates the target to route the matched request to.\n   */\n  target: AmplifyRouteTarget;\n\n  /** An object that dictates the target to fallback to if the original target returns a 404. */\n  fallback?: AmplifyRouteTarget;\n};\n\nexport type AmplifyImageSettings = {\n  /** Array of supported image widths */\n  sizes: number[];\n\n  /**\n   * Array of allowed external domains that can use Image Optimization.\n   * Leave empty for only allowing the deployment domain to use Image Optimization.\n   */\n  domains: string[];\n\n  /**\n   * Array of allowed external patterns that can use Image Optimization.\n   * Similar to `domains` but provides more control with RegExp.\n   */\n  remotePatterns: {\n    /** The protocol of the allowed remote pattern. Can be `http` or `https`. */\n    protocol?: \"http\" | \"https\";\n    /**\n     * The hostname of the allowed remote pattern.\n     * Can be literal or wildcard. Single `*` matches a single subdomain.\n     *  Double `**` matches any number of subdomains.\n     * We will disallow blanket wildcards of `**` with nothing else.\n     */\n    hostname: string;\n    /** The port of the allowed remote pattern. */\n    port?: string;\n    /** The pathname of the allowed remote pattern. */\n    pathname?: string;\n  }[];\n\n  /** Array of allowed output image formats. */\n  formats: (\"image/avif\" | \"image/webp\" | \"image/gif\" | \"image/png\" | \"image/jpeg\")[];\n\n  /** Cache duration (in seconds) for the optimized images. */\n  minimumCacheTTL: number;\n\n  /** Allow SVG input image URLs. This is disabled by default for security purposes. */\n  dangerouslyAllowSVG: boolean;\n};\n\nexport interface AmplifyDeployManifest {\n  /** The `version` property dictates the version of the Deployment Specification that has been implemented */\n  version: 1;\n\n  /**\n   * The routes property allows framework authors to leverage the routing rules primitive.\n   * Routing rules provide a mechanism by which incoming request paths can be routed to a specific target\n   * in the deployment bundle. Routing rules only dictate the destination of an incoming request and they are\n   * applied after rewrite/redirect rules have already transformed the request.\n   *\n   * Limits for routing rules:\n   * - A limit of 25 rules will be enforced on the routes array\n   */\n  routes?: AmplifyRoute[];\n\n  /**\n   * The imageSettings property allows framework authors to customize the behavior of the image optimization primitive,\n   * which provides on-demand optimization of images at runtime.\n   */\n  imageSettings?: AmplifyImageSettings;\n  /**\n   * Metadata about the provisioned compute resource(s). Each item in the array is an object that contains metadata\n   * about that compute resource.\n   *\n   * For example, given the following directory structure:\n   * ```\n   * .amplify\n   * └── compute\n   *     └── default\n   *         └── index.js\n   * ```\n   * The `computeResources` property would look like:\n   * ```\n   * [\n   *   {\n   *     name: 'default',\n   *     runtime: 'nodejs16.x',\n   *     entrypoint: 'index.js',\n   *   }\n   * ]\n   * ```\n   */\n  computeResources?: AmplifyComputeConfig[];\n\n  // Framework Metadata\n  framework: {\n    name: string;\n    version: string;\n  };\n}\n\nexport interface AWSAmplifyOptions {\n  catchAllStaticFallback?: boolean;\n  imageOptimization?: {\n    path?: string;\n    cacheControl?: string;\n  };\n  imageSettings?: AmplifyImageSettings;\n  runtime?: \"nodejs20.x\" | \"nodejs22.x\";\n}\n"
  },
  {
    "path": "src/presets/aws-amplify/utils.ts",
    "content": "import { writeFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { Nitro } from \"nitro/types\";\nimport { joinURL } from \"ufo\";\nimport type { AmplifyDeployManifest, AmplifyRoute, AmplifyRouteTarget } from \"./types.ts\";\n\nexport async function writeAmplifyFiles(nitro: Nitro) {\n  const outDir = nitro.options.output.dir;\n\n  // Generate routes\n  const routes: AmplifyRoute[] = [];\n\n  let hasWildcardPublicAsset = false;\n\n  if (nitro.options.awsAmplify?.imageOptimization && !nitro.options.static) {\n    const { path, cacheControl } = nitro.options.awsAmplify?.imageOptimization || {};\n    if (path) {\n      routes.push({\n        path,\n        target: {\n          kind: \"ImageOptimization\",\n          cacheControl,\n        },\n      });\n    }\n  }\n\n  const computeTarget: AmplifyRouteTarget = nitro.options.static\n    ? { kind: \"Static\" }\n    : { kind: \"Compute\", src: \"default\" };\n\n  for (const publicAsset of nitro.options.publicAssets) {\n    if (!publicAsset.baseURL || publicAsset.baseURL === \"/\") {\n      hasWildcardPublicAsset = true;\n      continue;\n    }\n    routes.push({\n      path: `${publicAsset.baseURL!.replace(/\\/$/, \"\")}/*`,\n      target: {\n        kind: \"Static\",\n        cacheControl:\n          publicAsset.maxAge > 0 ? `public, max-age=${publicAsset.maxAge}, immutable` : undefined,\n      },\n      fallback: publicAsset.fallthrough ? computeTarget : undefined,\n    });\n  }\n  if (hasWildcardPublicAsset && !nitro.options.static) {\n    routes.push({\n      path: \"/*.*\",\n      target: {\n        kind: \"Static\",\n      },\n      fallback: computeTarget,\n    });\n  }\n  routes.push({\n    path: \"/*\",\n    target: computeTarget,\n    fallback:\n      hasWildcardPublicAsset && nitro.options.awsAmplify?.catchAllStaticFallback\n        ? {\n            kind: \"Static\",\n          }\n        : undefined,\n  });\n\n  // Prefix with baseURL\n  for (const route of routes) {\n    if (route.path !== \"/*\") {\n      route.path = joinURL(nitro.options.baseURL, route.path);\n    }\n  }\n\n  // Generate deploy-manifest.json\n  const deployManifest: AmplifyDeployManifest = {\n    version: 1,\n    routes,\n    imageSettings: nitro.options.awsAmplify?.imageSettings || undefined,\n    computeResources: nitro.options.static\n      ? undefined\n      : [\n          {\n            name: \"default\",\n            entrypoint: \"server.js\",\n            runtime: nitro.options.awsAmplify?.runtime || \"nodejs20.x\",\n          },\n        ],\n    framework: {\n      name: nitro.options.framework.name || \"nitro\",\n      version: nitro.options.framework.version || \"0.0.0\",\n    },\n  };\n  await writeFile(resolve(outDir, \"deploy-manifest.json\"), JSON.stringify(deployManifest, null, 2));\n\n  // Write server.js (CJS)\n  if (!nitro.options.static) {\n    await writeFile(resolve(outDir, \"compute/default/server.js\"), `import(\"./index.mjs\")`);\n  }\n}\n"
  },
  {
    "path": "src/presets/aws-lambda/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nexport type { AwsLambdaOptions as PresetOptions } from \"./types.ts\";\n\nconst awsLambda = defineNitroPreset(\n  {\n    entry: \"./aws-lambda/runtime/aws-lambda\",\n    awsLambda: {\n      streaming: false,\n    },\n    hooks: {\n      \"rollup:before\": (nitro, rollupConfig) => {\n        if (nitro.options.awsLambda?.streaming) {\n          (rollupConfig.input as string) += \"-streaming\";\n        }\n      },\n    },\n  },\n  {\n    name: \"aws-lambda\" as const,\n  }\n);\n\nexport default [awsLambda] as const;\n"
  },
  {
    "path": "src/presets/aws-lambda/runtime/_utils.ts",
    "content": "import type { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from \"aws-lambda\";\nimport type { ServerRequest } from \"srvx\";\nimport { stringifyQuery } from \"ufo\";\n\n// Incoming (AWS => Web)\n\nexport function awsRequest(\n  event: APIGatewayProxyEvent | APIGatewayProxyEventV2,\n  context: unknown\n): ServerRequest {\n  const method = awsEventMethod(event);\n  const url = awsEventURL(event);\n  const headers = awsEventHeaders(event);\n  const body = awsEventBody(event);\n\n  const req = new Request(url, { method, headers, body }) as ServerRequest;\n\n  // srvx compatibility\n  req.runtime ??= { name: \"aws-lambda\" };\n  // @ts-expect-error (add to srvx types)\n  req.runtime.aws ??= { event, context } as any;\n\n  return new Request(url, { method, headers, body });\n}\n\nfunction awsEventMethod(event: APIGatewayProxyEvent | APIGatewayProxyEventV2): string {\n  return (\n    (event as APIGatewayProxyEvent).httpMethod ||\n    (event as APIGatewayProxyEventV2).requestContext?.http?.method ||\n    \"GET\"\n  );\n}\n\nfunction awsEventURL(event: APIGatewayProxyEvent | APIGatewayProxyEventV2): URL {\n  const hostname =\n    event.headers.host || event.headers.Host || event.requestContext?.domainName || \".\";\n\n  const path = (event as APIGatewayProxyEvent).path || (event as APIGatewayProxyEventV2).rawPath;\n\n  const query = awsEventQuery(event);\n\n  const protocol =\n    (event.headers[\"X-Forwarded-Proto\"] || event.headers[\"x-forwarded-proto\"]) === \"http\"\n      ? \"http\"\n      : \"https\";\n\n  return new URL(`${path}${query ? `?${query}` : \"\"}`, `${protocol}://${hostname}`);\n}\n\nfunction awsEventQuery(event: APIGatewayProxyEvent | APIGatewayProxyEventV2) {\n  if (typeof (event as APIGatewayProxyEventV2).rawQueryString === \"string\") {\n    return (event as APIGatewayProxyEventV2).rawQueryString;\n  }\n  const queryObj = {\n    ...event.queryStringParameters,\n    ...(event as APIGatewayProxyEvent).multiValueQueryStringParameters,\n  };\n  return stringifyQuery(queryObj);\n}\n\nfunction awsEventHeaders(event: APIGatewayProxyEvent | APIGatewayProxyEventV2): Headers {\n  const headers = new Headers();\n  for (const [key, value] of Object.entries(event.headers)) {\n    if (value) {\n      headers.set(key, value);\n    }\n  }\n  if (\"cookies\" in event && event.cookies) {\n    for (const cookie of event.cookies) {\n      headers.append(\"cookie\", cookie);\n    }\n  }\n  return headers;\n}\n\nfunction awsEventBody(event: APIGatewayProxyEvent | APIGatewayProxyEventV2): BodyInit | undefined {\n  if (!event.body) {\n    return undefined;\n  }\n  if (event.isBase64Encoded) {\n    return Buffer.from(event.body || \"\", \"base64\");\n  }\n  return event.body;\n}\n\n// Outgoing (Web => AWS)\n\nexport function awsResponseHeaders(response: Response) {\n  const headers: Record<string, string> = Object.create(null);\n  for (const [key, value] of response.headers) {\n    if (value) {\n      headers[key] = Array.isArray(value) ? value.join(\",\") : String(value);\n    }\n  }\n\n  const cookies = response.headers.getSetCookie();\n\n  return cookies.length > 0\n    ? {\n        headers,\n        cookies, // ApiGateway v2\n        multiValueHeaders: { \"set-cookie\": cookies }, // ApiGateway v1\n      }\n    : { headers };\n}\n\n// AWS Lambda proxy integrations requires base64 encoded buffers\n// binaryMediaTypes should be */*\n// see https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html\nexport async function awsResponseBody(\n  response: Response\n): Promise<{ body: string; isBase64Encoded?: boolean }> {\n  if (!response.body) {\n    return { body: \"\" };\n  }\n  const buffer = await toBuffer(response.body as any);\n  const contentType = response.headers.get(\"content-type\") || \"\";\n  return isTextType(contentType)\n    ? { body: buffer.toString(\"utf8\") }\n    : { body: buffer.toString(\"base64\"), isBase64Encoded: true };\n}\n\nfunction isTextType(contentType = \"\") {\n  return /^text\\/|\\/(javascript|json|xml)|utf-?8/i.test(contentType);\n}\n\nfunction toBuffer(data: ReadableStream): Promise<Buffer> {\n  return new Promise<Buffer>((resolve, reject) => {\n    const chunks: Buffer[] = [];\n    data\n      .pipeTo(\n        new WritableStream({\n          write(chunk) {\n            chunks.push(chunk);\n          },\n          close() {\n            resolve(Buffer.concat(chunks));\n          },\n          abort(reason) {\n            reject(reason);\n          },\n        })\n      )\n      .catch(reject);\n  });\n}\n"
  },
  {
    "path": "src/presets/aws-lambda/runtime/aws-lambda-streaming.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport { awsRequest, awsResponseHeaders } from \"./_utils.ts\";\n\nimport type { StreamingResponse } from \"@netlify/functions\";\nimport type { Readable } from \"node:stream\";\nimport type { APIGatewayProxyEventV2 } from \"aws-lambda\";\n\nconst nitroApp = useNitroApp();\n\nexport const handler = awslambda.streamifyResponse(\n  async (event: APIGatewayProxyEventV2, responseStream, context) => {\n    const request = awsRequest(event, context);\n\n    const response = await nitroApp.fetch(request);\n\n    const httpResponseMetadata: Omit<StreamingResponse, \"body\"> = {\n      statusCode: response.status,\n      ...awsResponseHeaders(response),\n    };\n\n    if (!httpResponseMetadata.headers![\"transfer-encoding\"]) {\n      httpResponseMetadata.headers![\"transfer-encoding\"] = \"chunked\";\n    }\n\n    const body =\n      response.body ??\n      new ReadableStream<string>({\n        start(controller) {\n          controller.enqueue(\"\");\n          controller.close();\n        },\n      });\n\n    const writer = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata);\n\n    const reader = body.getReader();\n    await streamToNodeStream(reader, responseStream);\n    writer.end();\n  }\n);\n\nasync function streamToNodeStream(\n  reader: Readable | ReadableStreamDefaultReader,\n  writer: NodeJS.WritableStream\n) {\n  let readResult = await reader.read();\n  while (!readResult.done) {\n    writer.write(readResult.value);\n    readResult = await reader.read();\n  }\n  writer.end();\n}\n"
  },
  {
    "path": "src/presets/aws-lambda/runtime/aws-lambda.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport { awsRequest, awsResponseHeaders, awsResponseBody } from \"./_utils.ts\";\n\nimport type {\n  APIGatewayProxyEvent,\n  APIGatewayProxyEventV2,\n  APIGatewayProxyResult,\n  APIGatewayProxyResultV2,\n  Context,\n} from \"aws-lambda\";\n\nconst nitroApp = useNitroApp();\n\nexport async function handler(\n  event: APIGatewayProxyEvent | APIGatewayProxyEventV2,\n  context: Context\n): Promise<APIGatewayProxyResult | APIGatewayProxyResultV2> {\n  const request = awsRequest(event, context);\n\n  const response = await nitroApp.fetch(request);\n\n  return {\n    statusCode: response.status,\n    ...awsResponseHeaders(response),\n    ...(await awsResponseBody(response)),\n  };\n}\n"
  },
  {
    "path": "src/presets/aws-lambda/types.ts",
    "content": "export interface AwsLambdaOptions {\n  streaming?: boolean;\n}\n"
  },
  {
    "path": "src/presets/azure/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { writeSWARoutes } from \"./utils.ts\";\n\nexport type { AzureOptions as PresetOptions } from \"./types.ts\";\n\nconst azureSWA = defineNitroPreset(\n  {\n    entry: \"./azure/runtime/azure-swa\",\n    output: {\n      serverDir: \"{{ output.dir }}/server/functions\",\n      publicDir: \"{{ output.dir }}/public/{{ baseURL }}\",\n    },\n    commands: {\n      preview: \"npx @azure/static-web-apps-cli start ./public --api-location ./server\",\n    },\n    hooks: {\n      async compiled(ctx: Nitro) {\n        await writeSWARoutes(ctx);\n      },\n    },\n  },\n  {\n    name: \"azure-swa\" as const,\n    stdName: \"azure_static\",\n  }\n);\n\nexport default [azureSWA] as const;\n"
  },
  {
    "path": "src/presets/azure/runtime/_utils.ts",
    "content": "import type { Cookie } from \"@azure/functions\";\nimport { parse } from \"cookie-es\";\n\nexport function getAzureParsedCookiesFromHeaders(headers: Headers): Cookie[] {\n  const setCookieHeader = headers.getSetCookie();\n  if (setCookieHeader.length === 0) {\n    return [];\n  }\n  const azureCookies: Cookie[] = [];\n  for (const setCookieStr of setCookieHeader) {\n    const setCookie = Object.entries(parse(setCookieStr));\n    if (setCookie.length === 0) {\n      continue;\n    }\n    const [[key, value], ..._setCookieOptions] = setCookie;\n    const setCookieOptions = Object.fromEntries(\n      _setCookieOptions.map(([k, v]) => [k.toLowerCase(), v])\n    );\n    const cookieObject: Cookie = {\n      name: key,\n      value,\n      domain: setCookieOptions.domain,\n      path: setCookieOptions.path,\n      expires: parseNumberOrDate(setCookieOptions.expires),\n      sameSite: setCookieOptions.samesite as \"Lax\" | \"Strict\" | \"None\",\n      maxAge: parseNumber(setCookieOptions[\"max-age\"]),\n      secure: setCookieStr.includes(\"Secure\") ? true : undefined,\n      httpOnly: setCookieStr.includes(\"HttpOnly\") ? true : undefined,\n    };\n    azureCookies.push(cookieObject);\n  }\n  return azureCookies;\n}\n\nfunction parseNumberOrDate(expires: string) {\n  const expiresAsNumber = parseNumber(expires);\n  if (expiresAsNumber !== undefined) {\n    return expiresAsNumber;\n  }\n  // Convert to Date if possible\n  const expiresAsDate = new Date(expires);\n  if (!Number.isNaN(expiresAsDate.getTime())) {\n    return expiresAsDate;\n  }\n}\n\nfunction parseNumber(maxAge: string) {\n  if (!maxAge) {\n    return undefined;\n  }\n  // Convert to number if possible\n  const maxAgeAsNumber = Number(maxAge);\n  if (!Number.isNaN(maxAgeAsNumber)) {\n    return maxAgeAsNumber;\n  }\n}\n"
  },
  {
    "path": "src/presets/azure/runtime/azure-swa.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { parseURL } from \"ufo\";\nimport { useNitroApp } from \"nitro/app\";\nimport { getAzureParsedCookiesFromHeaders } from \"./_utils.ts\";\n\nimport type { HttpRequest, HttpResponse, HttpResponseSimple } from \"@azure/functions\";\n\nconst nitroApp = useNitroApp();\n\nexport async function handle(context: { res: HttpResponse }, req: HttpRequest) {\n  let url: string;\n  if (req.headers[\"x-ms-original-url\"]) {\n    // This URL has been proxied as there was no static file matching it.\n    const parsedURL = parseURL(req.headers[\"x-ms-original-url\"]);\n    url = parsedURL.pathname + parsedURL.search;\n  } else {\n    // Because Azure SWA handles /api/* calls differently they\n    // never hit the proxy and we have to reconstitute the URL.\n    url = \"/api/\" + (req.params.url || \"\");\n  }\n\n  const request = new Request(url, {\n    method: req.method || undefined,\n    // https://github.com/Azure/azure-functions-nodejs-worker/issues/294\n    // https://github.com/Azure/azure-functions-host/issues/293\n    body: req.bufferBody ?? req.rawBody,\n  });\n\n  const response = await nitroApp.fetch(request);\n\n  // (v3 - current) https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=typescript%2Cwindows%2Cazure-cli&pivots=nodejs-model-v3#http-response\n  // (v4) https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=typescript%2Cwindows%2Cazure-cli&pivots=nodejs-model-v4#http-response\n  context.res = {\n    status: response.status,\n    body: response.body,\n    cookies: getAzureParsedCookiesFromHeaders(response.headers),\n    headers: Object.fromEntries(\n      [...response.headers.entries()].filter(([key]) => key !== \"set-cookie\")\n    ),\n  } satisfies HttpResponseSimple;\n}\n"
  },
  {
    "path": "src/presets/azure/types.ts",
    "content": "export interface AzureOptions {\n  config?: {\n    platform?: {\n      apiRuntime?: string;\n      [key: string]: unknown;\n    };\n    navigationFallback?: {\n      rewrite?: string;\n      [key: string]: unknown;\n    };\n    [key: string]: unknown;\n  };\n}\n"
  },
  {
    "path": "src/presets/azure/utils.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { join, resolve } from \"pathe\";\n\nexport async function writeSWARoutes(nitro: Nitro) {\n  const host = {\n    version: \"2.0\",\n  };\n\n  // https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=typescript%2Cwindows%2Cazure-cli&pivots=nodejs-model-v4#supported-versions\n  const supportedNodeVersions = new Set([\"20\", \"22\"]);\n  let nodeVersion = \"18\";\n  try {\n    const currentNodeVersion = JSON.parse(\n      await fsp.readFile(join(nitro.options.rootDir, \"package.json\"), \"utf8\")\n    ).engines.node;\n    if (supportedNodeVersions.has(currentNodeVersion)) {\n      nodeVersion = currentNodeVersion;\n    }\n  } catch {\n    const currentNodeVersion = process.versions.node.slice(0, 2);\n    if (supportedNodeVersions.has(currentNodeVersion)) {\n      nodeVersion = currentNodeVersion;\n    }\n  }\n\n  // Merge custom config into the generated config\n  const config = {\n    ...nitro.options.azure?.config,\n    // Overwrite routes for now, we will add existing routes after generating routes\n    routes: [] as Array<{ route: string; redirect?: string; rewrite?: string }>,\n    platform: {\n      apiRuntime: `node:${nodeVersion}`,\n      ...nitro.options.azure?.config?.platform,\n    },\n    navigationFallback: {\n      rewrite: \"/api/server\",\n      ...nitro.options.azure?.config?.navigationFallback,\n    },\n  };\n\n  const routeFiles = nitro._prerenderedRoutes || [];\n\n  const indexFileExists = routeFiles.some((route) => route.fileName === \"/index.html\");\n  if (!indexFileExists) {\n    config.routes.unshift(\n      {\n        route: \"/index.html\",\n        redirect: \"/\",\n      },\n      {\n        route: \"/\",\n        rewrite: \"/api/server\",\n      }\n    );\n  }\n\n  const suffix = \"/index.html\".length;\n  for (const { fileName } of routeFiles) {\n    if (!fileName || !fileName.endsWith(\"/index.html\")) {\n      continue;\n    }\n\n    config.routes.unshift({\n      route: fileName.slice(0, -suffix) || \"/\",\n      rewrite: fileName,\n    });\n  }\n\n  for (const { fileName } of routeFiles) {\n    if (!fileName || !fileName.endsWith(\".html\") || fileName.endsWith(\"index.html\")) {\n      continue;\n    }\n\n    const route = fileName.slice(0, -\".html\".length);\n    const existingRouteIndex = config.routes.findIndex((_route) => _route.route === route);\n    if (existingRouteIndex !== -1) {\n      config.routes.splice(existingRouteIndex, 1);\n    }\n    config.routes.unshift({\n      route,\n      rewrite: fileName,\n    });\n  }\n\n  // Prepend custom routes to the beginning of the routes array and override if they exist\n  if (\n    nitro.options.azure?.config &&\n    \"routes\" in nitro.options.azure.config &&\n    Array.isArray(nitro.options.azure.config.routes)\n  ) {\n    // We iterate through the reverse so the order in the custom config is persisted\n    for (const customRoute of nitro.options.azure.config.routes.reverse()) {\n      const existingRouteMatchIndex = config.routes.findIndex(\n        (value) => value.route === customRoute.route\n      );\n\n      if (existingRouteMatchIndex === -1) {\n        // If we don't find a match, put the customRoute at the beginning of the array\n        config.routes.unshift(customRoute);\n      } else {\n        // Otherwise override the existing route with our customRoute\n        config.routes[existingRouteMatchIndex] = customRoute;\n      }\n    }\n  }\n\n  const functionDefinition = {\n    entryPoint: \"handle\",\n    bindings: [\n      {\n        authLevel: \"anonymous\",\n        type: \"httpTrigger\",\n        direction: \"in\",\n        name: \"req\",\n        route: \"{*url}\",\n        methods: [\"delete\", \"get\", \"head\", \"options\", \"patch\", \"post\", \"put\"],\n      },\n      {\n        type: \"http\",\n        direction: \"out\",\n        name: \"res\",\n      },\n    ],\n  };\n\n  await writeFile(\n    resolve(nitro.options.output.serverDir, \"function.json\"),\n    JSON.stringify(functionDefinition, null, 2)\n  );\n  await writeFile(\n    resolve(nitro.options.output.serverDir, \"../host.json\"),\n    JSON.stringify(host, null, 2)\n  );\n  const stubPackageJson = resolve(nitro.options.output.serverDir, \"../package.json\");\n  await writeFile(stubPackageJson, JSON.stringify({ private: true }));\n  await writeFile(\n    resolve(nitro.options.rootDir, \"staticwebapp.config.json\"),\n    JSON.stringify(config, null, 2)\n  );\n  if (!indexFileExists) {\n    const baseURLSegments = nitro.options.baseURL.split(\"/\").filter(Boolean);\n    const relativePrefix = baseURLSegments.map(() => \"..\").join(\"/\");\n    await writeFile(\n      resolve(\n        nitro.options.output.publicDir,\n        relativePrefix ? `${relativePrefix}/index.html` : \"index.html\"\n      ),\n      \"\"\n    );\n  }\n}\n"
  },
  {
    "path": "src/presets/bun/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst bun = defineNitroPreset(\n  {\n    entry: \"./bun/runtime/bun\",\n    serveStatic: true,\n    // https://bun.sh/docs/runtime/modules#resolution\n    exportConditions: [\"bun\"],\n    commands: {\n      preview: \"bun run ./server/index.mjs\",\n    },\n  },\n  {\n    name: \"bun\" as const,\n  }\n);\n\nexport default [bun] as const;\n"
  },
  {
    "path": "src/presets/bun/runtime/bun.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type { ServerRequest } from \"srvx\";\nimport { serve } from \"srvx/bun\";\nimport wsAdapter from \"crossws/adapters/bun\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\nimport { trapUnhandledErrors } from \"#nitro/runtime/error/hooks\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst _parsedPort = Number.parseInt(process.env.NITRO_PORT ?? process.env.PORT ?? \"\");\nconst port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort;\nconst host = process.env.NITRO_HOST || process.env.HOST;\nconst cert = process.env.NITRO_SSL_CERT;\nconst key = process.env.NITRO_SSL_KEY;\n// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO\n\nconst nitroApp = useNitroApp();\n\nlet _fetch = nitroApp.fetch;\n\nconst ws = import.meta._websocket ? wsAdapter({ resolve: resolveWebsocketHooks }) : undefined;\n\nif (import.meta._websocket) {\n  _fetch = (req: ServerRequest) => {\n    if (req.headers.get(\"upgrade\") === \"websocket\") {\n      return ws!.handleUpgrade(req, req.runtime!.bun!.server) as Promise<Response>;\n    }\n    return nitroApp.fetch(req);\n  };\n}\n\nconst server = serve({\n  port,\n  hostname: host,\n  tls: cert && key ? { cert, key } : undefined,\n  fetch: _fetch,\n  bun: {\n    websocket: import.meta._websocket ? ws?.websocket : undefined,\n  },\n});\n\ntrapUnhandledErrors();\n\n// Scheduled tasks\nif (import.meta._tasks) {\n  startScheduleRunner({ waitUntil: server.waitUntil });\n}\n\nexport default {};\n"
  },
  {
    "path": "src/presets/cleavr/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst cleavr = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"cleavr\" as const,\n    stdName: \"cleavr\",\n  }\n);\n\nexport default [cleavr] as const;\n"
  },
  {
    "path": "src/presets/cloudflare/dev.ts",
    "content": "import { resolve } from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport type { Nitro } from \"nitro/types\";\nimport { findFile } from \"pkg-types\";\nimport { resolveModulePath } from \"exsolve\";\nimport { presetsDir } from \"nitro/meta\";\n\nexport async function cloudflareDevModule(nitro: Nitro) {\n  if (!nitro.options.dev) {\n    return; // Production doesn't need this\n  }\n\n  nitro.options.unenv.push({\n    meta: {\n      name: \"nitro:cloudflare-dev\",\n    },\n    alias: {\n      \"cloudflare:workers\": resolve(presetsDir, \"cloudflare/runtime/shims/workers.dev.mjs\"),\n    },\n  });\n\n  // Try to resolve wrangler\n  const wranglerPath = await resolveModulePath(\"wrangler\", {\n    from: nitro.options.rootDir,\n    try: true,\n  });\n  if (!wranglerPath) {\n    nitro.logger.warn(\n      \"Wrangler is not installed. Please install it using `npx nypm i wrangler` to enable dev emulation.\"\n    );\n    return;\n  }\n\n  const config = {\n    // compatibility with legacy nitro-cloudflare-dev module\n    ...(nitro.options as any).cloudflareDev,\n    ...nitro.options.cloudflare?.dev,\n  } as NonNullable<NonNullable<typeof nitro.options.cloudflare>[\"dev\"]>;\n\n  // Find wrangler.json > wrangler.jsonc > wrangler.toml\n  let configPath = config.configPath;\n  if (!configPath) {\n    configPath = await findFile([\"wrangler.json\", \"wrangler.jsonc\", \"wrangler.toml\"], {\n      startingFrom: nitro.options.rootDir,\n    }).catch(() => undefined);\n  }\n\n  // Resolve the persist dir\n  const persistDir = resolve(nitro.options.rootDir, config.persistDir || \".wrangler/state/v3\");\n\n  // Add `.wrangler/state/v3` to `.gitignore`\n  const gitIgnorePath = await findFile(\".gitignore\", {\n    startingFrom: nitro.options.rootDir,\n  }).catch(() => undefined);\n\n  // let addedToGitIgnore = false;\n  if (gitIgnorePath && persistDir === \".wrangler/state/v3\") {\n    const gitIgnore = await fs.readFile(gitIgnorePath, \"utf8\");\n    if (!gitIgnore.includes(\".wrangler/state/v3\")) {\n      await fs.writeFile(gitIgnorePath, gitIgnore + \"\\n.wrangler/state/v3\\n\").catch(() => {});\n      // addedToGitIgnore = true;\n    }\n  }\n\n  // Share config to the runtime\n  nitro.options.runtimeConfig.wrangler = {\n    ...nitro.options.runtimeConfig.wrangler,\n    configPath,\n    persistDir,\n    environment: config.environment,\n  };\n\n  // Add plugin to inject bindings to dev server\n  nitro.options.plugins = nitro.options.plugins || [];\n  nitro.options.plugins.unshift(\n    resolveModulePath(\"./cloudflare/runtime/plugin.dev\", {\n      from: presetsDir,\n      extensions: [\".mjs\", \".ts\"],\n    })\n  );\n}\n"
  },
  {
    "path": "src/presets/cloudflare/entry-exports.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { resolveModulePath } from \"exsolve\";\nimport { prettyPath } from \"../../utils/fs.ts\";\n\nconst RESOLVE_EXTENSIONS = [\".ts\", \".js\", \".mts\", \".mjs\"];\n\nexport async function setupEntryExports(nitro: Nitro) {\n  const exportsEntry = resolveExportsEntry(nitro);\n  if (!exportsEntry) return;\n\n  const originalEntry = nitro.options.entry;\n\n  const virtualEntryId = (nitro.options.entry = \"#nitro/virtual/cloudflare-server-entry\");\n  nitro.options.virtual[virtualEntryId] = /* ts */ `\n      export * from \"${exportsEntry}\";\n      export * from \"${originalEntry}\";\n      export { default } from \"${originalEntry}\";\n  `;\n}\n\nfunction resolveExportsEntry(nitro: Nitro) {\n  const entry = resolveModulePath(nitro.options.cloudflare?.exports || \"./exports.cloudflare.ts\", {\n    from: nitro.options.rootDir,\n    extensions: RESOLVE_EXTENSIONS,\n    try: true,\n  });\n\n  if (!entry && nitro.options.cloudflare?.exports) {\n    nitro.logger.warn(\n      `Your custom Cloudflare entrypoint \\`${prettyPath(nitro.options.cloudflare.exports)}\\` file does not exist.`\n    );\n  } else if (entry && !nitro.options.cloudflare?.exports) {\n    nitro.logger.info(`Detected \\`${prettyPath(entry)}\\` as Cloudflare entrypoint.`);\n  }\n\n  return entry;\n}\n"
  },
  {
    "path": "src/presets/cloudflare/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport type { Plugin } from \"rollup\";\nimport { resolve } from \"pathe\";\nimport { unenvCfExternals } from \"./unenv/preset.ts\";\nimport {\n  enableNodeCompat,\n  writeWranglerConfig,\n  writeCFRoutes,\n  writeCFHeaders,\n  writeCFPagesRedirects,\n} from \"./utils.ts\";\nimport { cloudflareDevModule } from \"./dev.ts\";\nimport { setupEntryExports } from \"./entry-exports.ts\";\n\n// Some bundlers (e.g. rolldown-vite) emit `createRequire(import.meta.url)` in\n// shared chunks. On Cloudflare Workers `import.meta.url` is `undefined`, which\n// causes `createRequire` to throw at runtime. This output plugin rewrites those\n// call sites to fall back to a synthetic `file:///` URL so that `createRequire`\n// succeeds and any subsequent `require()` calls go through the normal Node.js\n// compat layer provided by the Workers runtime.\n// Ref: https://github.com/nitrojs/nitro/issues/4132\nfunction guardCreateRequire(): Plugin {\n  return {\n    name: \"nitro:cloudflare-guard-createRequire\",\n    generateBundle(_options, bundle) {\n      for (const chunk of Object.values(bundle)) {\n        if (chunk.type === \"chunk\" && chunk.code?.includes(\"createRequire(import.meta.url)\")) {\n          chunk.code = chunk.code.replace(\n            /createRequire\\(import\\.meta\\.url\\)/g,\n            'createRequire(import.meta.url || \"file:///\")'\n          );\n        }\n      }\n    },\n  };\n}\n\nexport type { CloudflareOptions as PresetOptions } from \"./types.ts\";\n\nconst cloudflarePages = defineNitroPreset(\n  {\n    extends: \"base-worker\",\n    entry: \"./cloudflare/runtime/cloudflare-pages\",\n    exportConditions: [\"workerd\"],\n    minify: false,\n    commands: {\n      preview: \"npx wrangler --cwd ./ pages dev\",\n      deploy: \"npx wrangler --cwd ./ pages deploy\",\n    },\n    output: {\n      dir: \"{{ rootDir }}/dist\",\n      publicDir: \"{{ output.dir }}/{{ baseURL }}\",\n      serverDir: \"{{ output.dir }}/_worker.js\",\n    },\n    alias: {\n      // Hotfix: Cloudflare appends /index.html if mime is not found and things like ico are not in standard lite.js!\n      // https://github.com/nitrojs/nitro/pull/933\n      _mime: \"mime/index.js\",\n    },\n    wasm: {\n      lazy: false,\n      esmImport: true,\n    },\n    rollupConfig: {\n      output: {\n        entryFileNames: \"index.js\",\n        format: \"esm\",\n        inlineDynamicImports: false,\n      },\n      plugins: [guardCreateRequire()],\n    },\n    hooks: {\n      \"build:before\": async (nitro) => {\n        nitro.options.unenv.push(unenvCfExternals);\n        await enableNodeCompat(nitro);\n        await setupEntryExports(nitro);\n      },\n      async compiled(nitro: Nitro) {\n        await writeWranglerConfig(nitro, \"pages\");\n        await writeCFRoutes(nitro);\n        await writeCFHeaders(nitro, \"output\");\n        await writeCFPagesRedirects(nitro);\n      },\n    },\n  },\n  {\n    name: \"cloudflare-pages\" as const,\n    stdName: \"cloudflare_pages\",\n  }\n);\n\nconst cloudflarePagesStatic = defineNitroPreset(\n  {\n    extends: \"static\",\n    output: {\n      dir: \"{{ rootDir }}/dist\",\n      publicDir: \"{{ output.dir }}/{{ baseURL }}\",\n    },\n    commands: {\n      preview: \"npx wrangler --cwd ./ pages dev\",\n      deploy: \"npx wrangler --cwd ./ pages deploy\",\n    },\n    hooks: {\n      async compiled(nitro: Nitro) {\n        await writeCFHeaders(nitro, \"output\");\n        await writeCFPagesRedirects(nitro);\n      },\n    },\n  },\n  {\n    name: \"cloudflare-pages-static\" as const,\n    stdName: \"cloudflare_pages\",\n\n    static: true,\n  }\n);\n\nexport const cloudflareDev = defineNitroPreset(\n  {\n    extends: \"nitro-dev\",\n    modules: [cloudflareDevModule],\n  },\n  {\n    name: \"cloudflare-dev\" as const,\n    aliases: [\"cloudflare-module\", \"cloudflare-durable\", \"cloudflare-pages\"],\n    compatibilityDate: \"2025-07-13\",\n    dev: true,\n  }\n);\n\nconst cloudflareModule = defineNitroPreset(\n  {\n    extends: \"base-worker\",\n    entry: \"./cloudflare/runtime/cloudflare-module\",\n    output: {\n      publicDir: \"{{ output.dir }}/public/{{ baseURL }}\",\n    },\n    exportConditions: [\"workerd\"],\n    minify: false,\n    commands: {\n      preview: \"npx wrangler --cwd ./ dev\",\n      deploy: \"npx wrangler --cwd ./ deploy\",\n    },\n    rollupConfig: {\n      output: {\n        format: \"esm\",\n        exports: \"named\",\n        inlineDynamicImports: false,\n      },\n      plugins: [guardCreateRequire()],\n    },\n    wasm: {\n      lazy: false,\n      esmImport: true,\n    },\n    hooks: {\n      \"build:before\": async (nitro) => {\n        nitro.options.unenv.push(unenvCfExternals);\n        await enableNodeCompat(nitro);\n        await setupEntryExports(nitro);\n      },\n      async compiled(nitro: Nitro) {\n        await writeWranglerConfig(nitro, \"module\");\n        await writeCFHeaders(nitro, \"public\");\n\n        await writeFile(\n          resolve(nitro.options.output.dir, \"package.json\"),\n          JSON.stringify({ private: true, main: \"./server/index.mjs\" }, null, 2)\n        );\n        await writeFile(\n          resolve(nitro.options.output.dir, \"package-lock.json\"),\n          JSON.stringify({ lockfileVersion: 1 }, null, 2)\n        );\n      },\n    },\n  },\n  {\n    name: \"cloudflare-module\" as const,\n    stdName: \"cloudflare_workers\",\n  }\n);\n\nconst cloudflareDurable = defineNitroPreset(\n  {\n    extends: \"cloudflare-module\",\n    entry: \"./cloudflare/runtime/cloudflare-durable\",\n  },\n  {\n    name: \"cloudflare-durable\" as const,\n  }\n);\n\nexport default [\n  cloudflarePages,\n  cloudflarePagesStatic,\n  cloudflareModule,\n  cloudflareDurable,\n  cloudflareDev,\n];\n"
  },
  {
    "path": "src/presets/cloudflare/runtime/_module-handler.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type * as CF from \"@cloudflare/workers-types\";\nimport type { ServerRequest, ServerRuntimeContext } from \"srvx\";\n\nimport { runCronTasks } from \"#nitro/runtime/task\";\nimport { useNitroApp, useNitroHooks } from \"nitro/app\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport function createHandler<Env>(hooks: {\n  fetch: (\n    ...params: [\n      ...Parameters<NonNullable<ExportedHandler<Env>[\"fetch\"]>>,\n      url: URL,\n      cfContextExtras: any,\n    ]\n  ) => MaybePromise<Response | CF.Response | undefined>;\n}) {\n  const nitroApp = useNitroApp();\n  const nitroHooks = useNitroHooks();\n\n  return {\n    async fetch(request, env, context) {\n      (globalThis as any).__env__ = env;\n      augmentReq(request as any, { env: env as any, context });\n\n      const ctxExt = {};\n      const url = new URL(request.url);\n\n      // Preset-specific logic\n      if (hooks.fetch) {\n        const res = await hooks.fetch(request, env, context, url, ctxExt);\n        if (res) {\n          return res;\n        }\n      }\n\n      return (await nitroApp.fetch(request)) as any;\n    },\n\n    scheduled(controller, env, context) {\n      (globalThis as any).__env__ = env;\n      context.waitUntil(\n        nitroHooks.callHook(\"cloudflare:scheduled\", {\n          controller,\n          env,\n          context,\n        }) || Promise.resolve()\n      );\n      if (import.meta._tasks) {\n        context.waitUntil(\n          runCronTasks(controller.cron, {\n            context: {\n              cloudflare: {\n                env,\n                context,\n              },\n            },\n            payload: {},\n          })\n        );\n      }\n    },\n\n    email(message, env, context) {\n      (globalThis as any).__env__ = env;\n      context.waitUntil(\n        nitroHooks.callHook(\"cloudflare:email\", {\n          message: message as any,\n          event: message as any, // backward compat\n          env,\n          context,\n        }) || Promise.resolve()\n      );\n    },\n\n    queue(batch, env, context) {\n      (globalThis as any).__env__ = env;\n      context.waitUntil(\n        nitroHooks.callHook(\"cloudflare:queue\", {\n          batch,\n          event: batch,\n          env,\n          context,\n        }) || Promise.resolve()\n      );\n    },\n\n    tail(traces, env, context) {\n      (globalThis as any).__env__ = env;\n      context.waitUntil(\n        nitroHooks.callHook(\"cloudflare:tail\", {\n          traces,\n          env,\n          context,\n        }) || Promise.resolve()\n      );\n    },\n\n    trace(traces, env, context) {\n      (globalThis as any).__env__ = env;\n      context.waitUntil(\n        nitroHooks.callHook(\"cloudflare:trace\", {\n          traces,\n          env,\n          context,\n        }) || Promise.resolve()\n      );\n    },\n  } satisfies ExportedHandler<Env>;\n}\n\nexport function augmentReq(\n  cfReq: Request | CF.Request,\n  ctx: NonNullable<ServerRuntimeContext[\"cloudflare\"]>\n) {\n  const req = cfReq as ServerRequest;\n\n  req.ip = cfReq.headers.get(\"cf-connecting-ip\") || undefined;\n\n  req.runtime ??= { name: \"cloudflare\" };\n  req.runtime.cloudflare = { ...req.runtime.cloudflare, ...ctx };\n  req.waitUntil = ctx.context?.waitUntil.bind(ctx.context);\n}\n"
  },
  {
    "path": "src/presets/cloudflare/runtime/cloudflare-durable.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type * as CF from \"@cloudflare/workers-types\";\nimport { DurableObject } from \"cloudflare:workers\";\nimport wsAdapter from \"crossws/adapters/cloudflare\";\nimport { createHandler, augmentReq } from \"./_module-handler.ts\";\n\nimport { useNitroApp, useNitroHooks } from \"nitro/app\";\nimport { isPublicAssetURL } from \"#nitro/virtual/public-assets\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst DURABLE_BINDING = \"$DurableObject\";\nconst DURABLE_INSTANCE = \"server\";\n\ninterface Env {\n  ASSETS?: { fetch: typeof CF.fetch };\n  [DURABLE_BINDING]?: CF.DurableObjectNamespace;\n}\n\nconst nitroApp = useNitroApp();\nconst nitroHooks = useNitroHooks();\n\nconst getDurableStub = (env: Env) => {\n  const binding = env[DURABLE_BINDING];\n  if (!binding) {\n    throw new Error(`Durable Object binding \"${DURABLE_BINDING}\" not available.`);\n  }\n  const id = binding.idFromName(DURABLE_INSTANCE);\n  return binding.get(id);\n};\n\nconst ws = import.meta._websocket\n  ? wsAdapter({\n      resolve: resolveWebsocketHooks,\n      instanceName: DURABLE_INSTANCE,\n      bindingName: DURABLE_BINDING,\n    })\n  : undefined;\n\nexport default createHandler<Env>({\n  fetch(request, env, context, url, ctxExt) {\n    // Static assets fallback (optional binding)\n    if (env.ASSETS && isPublicAssetURL(url.pathname)) {\n      return env.ASSETS.fetch(request as any);\n    }\n\n    // Expose stub fetch to the context\n    ctxExt.durableFetch = (req = request) => getDurableStub(env).fetch(req as any);\n\n    // Websocket upgrade\n    // https://crossws.unjs.io/adapters/cloudflare#durable-objects\n    if (import.meta._websocket && request.headers.get(\"upgrade\") === \"websocket\") {\n      return ws!.handleUpgrade(request, env, context);\n    }\n  },\n});\n\nexport class $DurableObject extends DurableObject {\n  constructor(state: DurableObjectState, env: Record<string, any>) {\n    super(state, env);\n    state.waitUntil(\n      nitroHooks.callHook(\"cloudflare:durable:init\", this, {\n        state,\n        env,\n      }) || Promise.resolve()\n    );\n    if (import.meta._websocket) {\n      ws!.handleDurableInit(this, state, env);\n    }\n  }\n\n  override fetch(request: Request) {\n    augmentReq(request, {\n      env: this.env,\n      context: this.ctx as any,\n    });\n\n    if (import.meta._websocket && request.headers.get(\"upgrade\") === \"websocket\") {\n      return ws!.handleDurableUpgrade(this, request);\n    }\n\n    return nitroApp.fetch(request);\n  }\n\n  override alarm(): void | Promise<void> {\n    this.ctx.waitUntil(nitroHooks.callHook(\"cloudflare:durable:alarm\", this) || Promise.resolve());\n  }\n\n  override async webSocketMessage(client: WebSocket, message: ArrayBuffer | string) {\n    if (import.meta._websocket) {\n      return ws!.handleDurableMessage(this, client, message);\n    }\n  }\n\n  override async webSocketClose(\n    client: WebSocket,\n    code: number,\n    reason: string,\n    wasClean: boolean\n  ) {\n    if (import.meta._websocket) {\n      return ws!.handleDurableClose(this, client, code, reason, wasClean);\n    }\n  }\n}\n"
  },
  {
    "path": "src/presets/cloudflare/runtime/cloudflare-module.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type { fetch } from \"@cloudflare/workers-types\";\nimport wsAdapter from \"crossws/adapters/cloudflare\";\n\nimport { isPublicAssetURL } from \"#nitro/virtual/public-assets\";\nimport { createHandler } from \"./_module-handler.ts\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst ws = import.meta._websocket ? wsAdapter({ resolve: resolveWebsocketHooks }) : undefined;\n\ninterface Env {\n  ASSETS?: { fetch: typeof fetch };\n}\n\nexport default createHandler<Env>({\n  fetch(cfRequest, env, context, url) {\n    // Static assets fallback (optional binding)\n    if (env.ASSETS && isPublicAssetURL(url.pathname)) {\n      return env.ASSETS.fetch(cfRequest as any);\n    }\n\n    // Websocket upgrade\n    // https://crossws.unjs.io/adapters/cloudflare\n    if (import.meta._websocket && cfRequest.headers.get(\"upgrade\") === \"websocket\") {\n      return ws!.handleUpgrade(cfRequest, env, context);\n    }\n  },\n});\n"
  },
  {
    "path": "src/presets/cloudflare/runtime/cloudflare-pages.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type {\n  Request as CFRequest,\n  EventContext,\n  ExecutionContext,\n} from \"@cloudflare/workers-types\";\nimport wsAdapter from \"crossws/adapters/cloudflare\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { isPublicAssetURL } from \"#nitro/virtual/public-assets\";\nimport { runCronTasks } from \"#nitro/runtime/task\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nimport { augmentReq } from \"./_module-handler.ts\";\n\n/**\n * Reference: https://developers.cloudflare.com/workers/runtime-apis/fetch-event/#parameters\n */\n\ninterface CFPagesEnv {\n  ASSETS: { fetch: (request: CFRequest) => Promise<Response> };\n  CF_PAGES: \"1\";\n  CF_PAGES_BRANCH: string;\n  CF_PAGES_COMMIT_SHA: string;\n  CF_PAGES_URL: string;\n  [key: string]: any;\n}\n\nconst nitroApp = useNitroApp();\n\nconst ws = import.meta._websocket ? wsAdapter({ resolve: resolveWebsocketHooks }) : undefined;\n\nexport default {\n  async fetch(cfReq: CFRequest, env: CFPagesEnv, context: EventContext<CFPagesEnv, string, any>) {\n    augmentReq(cfReq, {\n      env,\n      context: context as any,\n    });\n\n    // Websocket upgrade\n    // https://crossws.unjs.io/adapters/cloudflare\n    if (import.meta._websocket && cfReq.headers.get(\"upgrade\") === \"websocket\") {\n      return ws!.handleUpgrade(cfReq, env, context as unknown as ExecutionContext);\n    }\n\n    const url = new URL(cfReq.url);\n    if (env.ASSETS /* !miniflare */ && isPublicAssetURL(url.pathname)) {\n      return env.ASSETS.fetch(cfReq);\n    }\n\n    return nitroApp.fetch(cfReq as any);\n  },\n  scheduled(event: any, env: CFPagesEnv, context: ExecutionContext) {\n    if (import.meta._tasks) {\n      (globalThis as any).__env__ = env;\n      context.waitUntil(\n        runCronTasks(event.cron, {\n          context: {\n            cloudflare: {\n              env,\n              context,\n            },\n          },\n          payload: {},\n        })\n      );\n    }\n  },\n};\n"
  },
  {
    "path": "src/presets/cloudflare/runtime/plugin.dev.ts",
    "content": "import type { NitroAppPlugin } from \"nitro/types\";\nimport type { GetPlatformProxyOptions, PlatformProxy } from \"wrangler\";\n\nimport { useRuntimeConfig } from \"nitro/runtime-config\";\n\nconst proxy = await _getPlatformProxy().catch((error) => {\n  console.error(\"Failed to initialize wrangler bindings proxy\", error);\n  return _createStubProxy();\n});\n\n(globalThis as any).__env__ = proxy.env;\n(globalThis as any).__wait_until__ = proxy.ctx.waitUntil.bind(proxy.ctx);\n\nconst cloudflareDevPlugin: NitroAppPlugin = function (nitroApp) {\n  nitroApp.hooks.hook(\"request\", async (event) => {\n    const request = event.req;\n\n    (request as any).runtime ??= { name: \"cloudflare\" };\n    (request as any).runtime.cloudflare = {\n      ...(request as any).runtime.cloudflare,\n      env: proxy.env,\n      context: proxy.ctx,\n    };\n    (request as any).waitUntil = proxy.ctx.waitUntil.bind(proxy.ctx);\n    (request as any).cf = proxy.cf;\n  });\n\n  // https://github.com/pi0/nitro-cloudflare-dev/issues/5\n  // https://github.com/unjs/hookable/issues/98\n  // @ts-expect-error\n  nitroApp.hooks._hooks.request.unshift(nitroApp.hooks._hooks.request.pop());\n\n  // Dispose proxy when Nitro is closed\n  nitroApp.hooks.hook(\"close\", () => {\n    return proxy?.dispose();\n  });\n};\n\nexport default cloudflareDevPlugin;\n\nasync function _getPlatformProxy() {\n  const pkg = \"wrangler\"; // bypass bundler\n  const { getPlatformProxy } = (await import(/* @vite-ignore */ pkg).catch(() => {\n    throw new Error(\n      \"Package `wrangler` not found, please install it with: `npx nypm@latest add -D wrangler`\"\n    );\n  })) as typeof import(\"wrangler\");\n\n  const runtimeConfig: {\n    wrangler: {\n      configPath: string;\n      persistDir: string;\n      environment?: string;\n    };\n  } = useRuntimeConfig() as any;\n\n  const proxyOptions: GetPlatformProxyOptions = {\n    configPath: runtimeConfig.wrangler.configPath,\n    persist: { path: runtimeConfig.wrangler.persistDir },\n  };\n  // TODO: investigate why\n  // https://github.com/pi0/nitro-cloudflare-dev/issues/51\n  if (runtimeConfig.wrangler.environment) {\n    proxyOptions.environment = runtimeConfig.wrangler.environment;\n  }\n  const proxy = await getPlatformProxy(proxyOptions);\n\n  return proxy;\n}\n\nfunction _createStubProxy(): PlatformProxy {\n  return {\n    env: {},\n    cf: {} as any,\n    ctx: {\n      waitUntil() {},\n      passThroughOnException() {},\n      props: {},\n    },\n    caches: {\n      open(): Promise<_CacheStub> {\n        const result = Promise.resolve(new _CacheStub());\n        return result;\n      },\n      get default(): _CacheStub {\n        return new _CacheStub();\n      },\n    },\n    dispose: () => Promise.resolve(),\n  };\n}\n\nclass _CacheStub {\n  delete(): Promise<boolean> {\n    const result = Promise.resolve(false);\n    return result;\n  }\n\n  match() {\n    const result = Promise.resolve(undefined);\n    return result;\n  }\n\n  put(): Promise<void> {\n    const result = Promise.resolve();\n    return result;\n  }\n}\n"
  },
  {
    "path": "src/presets/cloudflare/runtime/shims/workers.dev.mjs",
    "content": "// Shim for \"cloudflare:workers\" import in dev environment\n\n// unenv shim respects __env__\nexport { env } from \"unenv/node/internal/process/env\";\n\nexport async function waitUntil(promise) {\n  await globalThis.__wait_until__?.(promise);\n}\n\nexport function withEnv(newEnv, fn) {\n  throw new Error(\"cf.withEnv is not implemented in dev env currently.\");\n}\n\nclass NotImplemented {\n  constructor() {\n    throw new Error(\"Not implemented in dev env currently.\");\n  }\n}\n\nexport class DurableObject extends NotImplemented {}\nexport class RpcPromise extends NotImplemented {}\nexport class RpcProperty extends NotImplemented {}\nexport class RpcStub extends NotImplemented {}\nexport class RpcTarget extends NotImplemented {}\nexport class ServiceStub extends NotImplemented {}\nexport class WorkerEntrypoint extends NotImplemented {}\nexport class WorkflowEntrypoint extends NotImplemented {}\n"
  },
  {
    "path": "src/presets/cloudflare/types.ts",
    "content": "import type {\n  ExecutionContext,\n  ForwardableEmailMessage,\n  MessageBatch,\n  ScheduledController,\n  TraceItem,\n} from \"@cloudflare/workers-types\";\nimport type { DurableObject } from \"cloudflare:workers\";\n\nimport type { Config as _Config, ComputedFields as _ComputedFields } from \"./wrangler/config.ts\";\n\nexport type WranglerConfig = Partial<Omit<_Config, keyof _ComputedFields>>;\n\n/**\n * https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes\n */\nexport interface CloudflarePagesRoutes {\n  /** Defines the version of the schema. Currently there is only one version of the schema (version 1), however, we may add more in the future and aim to be backwards compatible. */\n  version?: 1;\n\n  /** Defines routes that will be invoked by Functions. Accepts wildcard behavior. */\n  include?: string[];\n\n  /** Defines routes that will not be invoked by Functions. Accepts wildcard behavior. `exclude` always take priority over `include`. */\n  exclude?: string[];\n}\n\nexport interface CloudflareOptions {\n  /**\n   * Configuration for the Cloudflare Deployments.\n   *\n   * **NOTE:** This option is only effective if `deployConfig` is enabled.\n   */\n  wrangler?: WranglerConfig;\n\n  /**\n   * Enable automatic generation of `.wrangler/deploy/config.json`.\n   *\n   * **IMPORTANT:** Enabling this option will cause settings from cloudflare dashboard (including environment variables) to be disabled and discarded.\n   *\n   * More info: https://developers.cloudflare.com/workers/wrangler/configuration#generated-wrangler-configuration\n   */\n  deployConfig?: boolean;\n\n  /**\n   * Enable native Node.js compatibility support.\n   *\n   * If this option disabled, pure unenv polyfills will be used instead.\n   *\n   * If not set, will be auto enabled if `nodejs_compat` or `nodejs_compat_v2` is detected in `wrangler.toml` or `wrangler.json`.\n   */\n  nodeCompat?: boolean;\n\n  /**\n   * Options for dev emulation.\n   */\n  dev?: {\n    configPath?: string;\n    environment?: string;\n    persistDir?: string;\n  };\n\n  pages?: {\n    /**\n     * Nitro will automatically generate a `_routes.json` that controls which files get served statically and\n     * which get served by the Worker. Using this config will override the automatic `_routes.json`. Or, if the\n     * `merge` options is set, it will merge the user-set routes with the auto-generated ones, giving priority\n     * to the user routes.\n     *\n     * @see https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes\n     *\n     * There are a maximum of 100 rules, and you must have at least one include rule. Wildcards are accepted.\n     *\n     * If any fields are unset, they default to:\n     *\n     * ```json\n     * {\n     *   \"version\": 1,\n     *   \"include\": [\"/*\"],\n     *   \"exclude\": []\n     * }\n     * ```\n     */\n    routes?: CloudflarePagesRoutes;\n    /**\n     * If set to `false`, nitro will disable the automatically generated `_routes.json` and instead use the user-set only ones.\n     *\n     * @default true\n     */\n    defaultRoutes?: boolean;\n  };\n\n  /**\n   * Custom Cloudflare exports additional classes such as WorkflowEntrypoint.\n   */\n  exports?: string;\n}\n\ntype DurableObjectState = ConstructorParameters<typeof DurableObject>[0];\n\ndeclare module \"nitro/types\" {\n  export interface NitroRuntimeHooks {\n    // https://developers.cloudflare.com/workers/runtime-apis/handlers/scheduled/\n    \"cloudflare:scheduled\": (_: {\n      controller: ScheduledController;\n      env: unknown;\n      context: ExecutionContext;\n    }) => void;\n    // https://developers.cloudflare.com/email-routing/email-workers/runtime-api\n    \"cloudflare:email\": (_: {\n      message: ForwardableEmailMessage;\n      /** @deprecated please use `message` */\n      event: ForwardableEmailMessage;\n      env: unknown;\n      context: ExecutionContext;\n    }) => void;\n    // https://developers.cloudflare.com/queues/configuration/javascript-apis/#consumer\n    \"cloudflare:queue\": (_: {\n      batch: MessageBatch;\n      /** @deprecated please use `batch` */\n      event: MessageBatch;\n      env: unknown;\n      context: ExecutionContext;\n    }) => void;\n    // https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/\n    \"cloudflare:tail\": (_: {\n      traces: TraceItem[];\n      env: unknown;\n      context: ExecutionContext;\n    }) => void;\n    \"cloudflare:trace\": (_: {\n      traces: TraceItem[];\n      env: unknown;\n      context: ExecutionContext;\n    }) => void;\n\n    \"cloudflare:durable:init\": (\n      durable: DurableObject,\n      _: {\n        state: DurableObjectState;\n        env: unknown;\n      }\n    ) => void;\n\n    \"cloudflare:durable:alarm\": (durable: DurableObject) => void;\n  }\n}\n"
  },
  {
    "path": "src/presets/cloudflare/unenv/node-compat.ts",
    "content": "// Auto generated at 2025-10-05\n// Source: https://platform-node-compat.pi0.workers.dev/\n// Do not edit this file manually\n\n// prettier-ignore\nexport const builtnNodeModules = [\n  \"node:_http_agent\",\n  \"node:_http_client\",\n  \"node:_http_common\", // Missing exports: CRLF, HTTPParser, freeParser, isLenient, parsers, prepareError\n  \"node:_http_incoming\", // Missing exports: readStart, readStop\n  \"node:_http_outgoing\",\n  \"node:_http_server\",\n  \"node:_stream_duplex\",\n  \"node:_stream_passthrough\",\n  \"node:_stream_readable\",\n  \"node:_stream_transform\",\n  \"node:_stream_writable\",\n  \"node:_tls_common\",\n  \"node:_tls_wrap\", // Missing exports: Server, createServer\n  \"node:assert\", // Missing exports: Assert, CallTracker\n  \"node:assert/strict\", // Missing exports: Assert, CallTracker\n  \"node:async_hooks\",\n  \"node:buffer\",\n  \"node:constants\", // Missing exports: O_DIRECT, O_NOATIME, RTLD_DEEPBIND, SIGPOLL, SIGPWR, SIGSTKFLT, defaultCipherList\n  \"node:crypto\", // Missing exports: argon2, argon2Sync, decapsulate, encapsulate\n  \"node:diagnostics_channel\",\n  \"node:dns\", // Missing exports: resolveTlsa\n  \"node:dns/promises\", // Missing exports: resolveTlsa\n  \"node:events\", // Missing exports: captureRejections, init\n  \"node:fs\", // Missing exports: Utf8Stream, mkdtempDisposableSync\n  \"node:fs/promises\", // Missing exports: mkdtempDisposable\n  \"node:http\",\n  \"node:http2\",\n  \"node:https\",\n  \"node:module\",\n  \"node:net\",\n  \"node:os\",\n  \"node:path\",\n  \"node:path/posix\",\n  \"node:path/win32\",\n  \"node:process\",\n  \"node:querystring\",\n  \"node:stream\",\n  \"node:stream/consumers\",\n  \"node:stream/promises\",\n  \"node:stream/web\",\n  \"node:string_decoder\",\n  \"node:test\", // Missing exports: after, afterEach, assert, before, beforeEach, describe, it, only, run, skip, snapshot, suite, test, todo\n  \"node:timers\",\n  \"node:timers/promises\",\n  \"node:tls\", // Missing exports: getCACertificates, setDefaultCACertificates\n  \"node:url\", // Missing exports: URLPattern, fileURLToPathBuffer\n  \"node:util\", // Missing exports: diff, setTraceSigInt\n  \"node:util/types\",\n  \"node:zlib\", // Missing exports: ZstdCompress, ZstdDecompress, createZstdCompress, createZstdDecompress, zstdCompress, zstdCompressSync, zstdDecompress, zstdDecompressSync\n];\n\n// prettier-ignore\nexport const unsupportedNodeModules = [\n  \"node:_stream_wrap\",\n  \"node:child_process\",\n  \"node:cluster\",\n  \"node:console\",\n  \"node:dgram\",\n  \"node:domain\",\n  \"node:inspector\",\n  \"node:inspector/promises\",\n  \"node:perf_hooks\",\n  \"node:punycode\",\n  \"node:readline\",\n  \"node:readline/promises\",\n  \"node:repl\",\n  \"node:sys\",\n  \"node:trace_events\",\n  \"node:tty\",\n  \"node:v8\",\n  \"node:vm\",\n  \"node:wasi\",\n  \"node:worker_threads\",\n  \"node:sea\",\n  \"node:sqlite\",\n  \"node:test/reporters\",\n];\n"
  },
  {
    "path": "src/presets/cloudflare/unenv/preset.ts",
    "content": "import type { Preset } from \"unenv\";\nimport * as workerdNodeCompat from \"./node-compat.ts\";\n\n// https://platform-node-compat.pi0.workers.dev/\n\nexport const unenvCfNodeCompat: Preset = {\n  meta: {\n    name: \"nitro:cloudflare-node-compat\",\n  },\n  external: workerdNodeCompat.builtnNodeModules,\n  alias: {\n    ...Object.fromEntries(\n      workerdNodeCompat.builtnNodeModules.flatMap((m) => [\n        [m, m],\n        [m.replace(\"node:\", \"\"), m],\n      ])\n    ),\n  },\n  inject: {\n    global: \"unenv/polyfill/globalthis\",\n    process: \"node:process\",\n    clearImmediate: [\"node:timers\", \"clearImmediate\"],\n    setImmediate: [\"node:timers\", \"setImmediate\"],\n    Buffer: [\"node:buffer\", \"Buffer\"],\n  },\n};\n\nexport const unenvCfExternals: Preset = {\n  meta: {\n    name: \"nitro:cloudflare-externals\",\n  },\n  external: [\n    \"cloudflare:email\",\n    \"cloudflare:sockets\",\n    \"cloudflare:workers\",\n    \"cloudflare:workflows\",\n  ],\n};\n"
  },
  {
    "path": "src/presets/cloudflare/utils.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport type { WranglerConfig, CloudflarePagesRoutes } from \"./types.ts\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { relative, dirname, extname } from \"node:path\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport { parseTOML, parseJSONC } from \"confbox\";\nimport { readGitConfig, readPackageJSON, findNearestFile } from \"pkg-types\";\nimport { defu } from \"defu\";\nimport { glob } from \"tinyglobby\";\nimport { join, resolve } from \"pathe\";\nimport {\n  joinURL,\n  hasProtocol,\n  withLeadingSlash,\n  withTrailingSlash,\n  withoutLeadingSlash,\n} from \"ufo\";\nimport { unenvCfNodeCompat } from \"./unenv/preset.ts\";\n\nexport async function writeCFRoutes(nitro: Nitro) {\n  const _cfPagesConfig = nitro.options.cloudflare?.pages || {};\n  const routes: CloudflarePagesRoutes = {\n    version: _cfPagesConfig.routes?.version || 1,\n    include: _cfPagesConfig.routes?.include || [\"/*\"],\n    exclude: _cfPagesConfig.routes?.exclude || [],\n  };\n\n  const writeRoutes = () =>\n    writeFile(\n      resolve(nitro.options.output.dir, \"_routes.json\"),\n      JSON.stringify(routes, undefined, 2),\n      true\n    );\n\n  if (_cfPagesConfig.defaultRoutes === false) {\n    await writeRoutes();\n    return;\n  }\n\n  // Exclude public assets from hitting the worker\n  const explicitPublicAssets = nitro.options.publicAssets.filter((dir, index, array) => {\n    if (dir.fallthrough || !dir.baseURL) {\n      return false;\n    }\n\n    const normalizedBase = withoutLeadingSlash(dir.baseURL);\n\n    return !array.some(\n      (otherDir, otherIndex) =>\n        otherIndex !== index &&\n        normalizedBase.startsWith(withoutLeadingSlash(withTrailingSlash(otherDir.baseURL)))\n    );\n  });\n\n  // Explicit prefixes\n  routes.exclude!.push(\n    ...explicitPublicAssets\n      .map((asset) => joinURL(nitro.options.baseURL, asset.baseURL || \"/\", \"*\"))\n      .sort(comparePaths)\n  );\n\n  // Unprefixed assets\n  const publicAssetFiles = await glob(\"**\", {\n    cwd: nitro.options.output.dir,\n    absolute: false,\n    dot: true,\n    ignore: [\n      \"_worker.js\",\n      \"_worker.js.map\",\n      \"nitro.json\",\n      ...routes.exclude!.map((path) => withoutLeadingSlash(path.replace(/\\/\\*$/, \"/**\"))),\n    ],\n  });\n  // Remove index.html or the .html extension to support pages pre-rendering\n  routes.exclude!.push(\n    ...publicAssetFiles\n      .map(\n        (i) =>\n          withLeadingSlash(i)\n            .replace(/\\/index\\.html$/, \"\")\n            .replace(/\\.html$/, \"\") || \"/\"\n      )\n      .sort(comparePaths)\n  );\n\n  // Only allow 100 rules in total (include + exclude)\n  routes.exclude!.splice(100 - routes.include!.length);\n\n  await writeRoutes();\n}\n\nfunction comparePaths(a: string, b: string) {\n  return a.split(\"/\").length - b.split(\"/\").length || a.localeCompare(b);\n}\n\nexport async function writeCFHeaders(nitro: Nitro, outdir: \"public\" | \"output\") {\n  const headersPath = join(\n    outdir === \"public\" ? nitro.options.output.publicDir : nitro.options.output.dir,\n    \"_headers\"\n  );\n  const contents = [];\n\n  const rules = Object.entries(nitro.options.routeRules).sort(\n    (a, b) => b[0].split(/\\/(?!\\*)/).length - a[0].split(/\\/(?!\\*)/).length\n  );\n\n  for (const [path, routeRules] of rules.filter(([_, routeRules]) => routeRules.headers)) {\n    const headers = [\n      joinURL(nitro.options.baseURL, path.replace(\"/**\", \"/*\")),\n      ...Object.entries({ ...routeRules.headers }).map(\n        ([header, value]) => `  ${header}: ${value}`\n      ),\n    ].join(\"\\n\");\n\n    contents.push(headers);\n  }\n\n  if (existsSync(headersPath)) {\n    const currentHeaders = await readFile(headersPath, \"utf8\");\n    if (/^\\/\\* /m.test(currentHeaders)) {\n      nitro.logger.info(\n        \"Not adding Nitro fallback to `_headers` (as an existing fallback was found).\"\n      );\n      return;\n    }\n    nitro.logger.info(\"Adding Nitro fallback to `_headers` to handle all unmatched routes.\");\n    contents.unshift(currentHeaders);\n  }\n\n  await writeFile(headersPath, contents.join(\"\\n\"), true);\n}\n\nexport async function writeCFPagesRedirects(nitro: Nitro) {\n  const redirectsPath = join(nitro.options.output.dir, \"_redirects\");\n  const staticFallback = existsSync(join(nitro.options.output.publicDir, \"404.html\"))\n    ? `${joinURL(nitro.options.baseURL, \"/*\")} ${joinURL(nitro.options.baseURL, \"/404.html\")} 404`\n    : \"\";\n  const contents = [staticFallback];\n  const rules = Object.entries(nitro.options.routeRules).sort(\n    (a, b) => a[0].split(/\\/(?!\\*)/).length - b[0].split(/\\/(?!\\*)/).length\n  );\n\n  for (const [key, routeRules] of rules.filter(([_, routeRules]) => routeRules.redirect)) {\n    const code = routeRules.redirect!.status;\n    const from = joinURL(nitro.options.baseURL, key.replace(\"/**\", \"/*\"));\n    const to = hasProtocol(routeRules.redirect!.to, { acceptRelative: true })\n      ? routeRules.redirect!.to\n      : joinURL(nitro.options.baseURL, routeRules.redirect!.to);\n    contents.unshift(`${from}\\t${to}\\t${code}`);\n  }\n\n  if (existsSync(redirectsPath)) {\n    const currentRedirects = await readFile(redirectsPath, \"utf8\");\n    if (/^\\/\\* /m.test(currentRedirects)) {\n      nitro.logger.info(\n        \"Not adding Nitro fallback to `_redirects` (as an existing fallback was found).\"\n      );\n      return;\n    }\n    nitro.logger.info(\"Adding Nitro fallback to `_redirects` to handle all unmatched routes.\");\n    contents.unshift(currentRedirects);\n  }\n\n  await writeFile(redirectsPath, contents.join(\"\\n\"), true);\n}\n\nexport async function enableNodeCompat(nitro: Nitro) {\n  nitro.options.cloudflare ??= {};\n\n  nitro.options.cloudflare.deployConfig ??= true;\n  nitro.options.cloudflare.nodeCompat ??= true;\n  if (nitro.options.cloudflare.nodeCompat) {\n    nitro.options.rolldownConfig ??= {};\n    nitro.options.rolldownConfig.platform ??= \"node\";\n    nitro.options.unenv.push(unenvCfNodeCompat);\n  }\n}\n\nconst extensionParsers = {\n  \".json\": parseJSONC,\n  \".jsonc\": parseJSONC,\n  \".toml\": parseTOML,\n} as const;\n\nasync function readWranglerConfig(\n  nitro: Nitro\n): Promise<{ configPath?: string; config?: WranglerConfig }> {\n  const configPath = await findNearestFile([\"wrangler.json\", \"wrangler.jsonc\", \"wrangler.toml\"], {\n    startingFrom: nitro.options.rootDir,\n  }).catch(() => undefined);\n  if (!configPath) {\n    return {};\n  }\n  const userConfigText = await readFile(configPath, \"utf8\");\n  const parser = extensionParsers[extname(configPath) as keyof typeof extensionParsers];\n  if (!parser) {\n    /* unreachable */\n    throw new Error(`Unsupported config file format: ${configPath}`);\n  }\n  const config = parser(userConfigText) as WranglerConfig;\n  return { configPath, config };\n}\n\n// https://developers.cloudflare.com/workers/wrangler/configuration/#generated-wrangler-configuration\nexport async function writeWranglerConfig(nitro: Nitro, cfTarget: \"pages\" | \"module\") {\n  // Skip if not enabled\n  if (!nitro.options.cloudflare?.deployConfig) {\n    return;\n  }\n\n  // Compute path to generated wrangler.json\n  const wranglerConfigDir = nitro.options.output.serverDir;\n  const wranglerConfigPath = join(wranglerConfigDir, \"wrangler.json\");\n\n  // Default configs\n  const defaults: WranglerConfig = {};\n\n  // Config overrides\n  const overrides: WranglerConfig = {};\n\n  // Compatibility date\n  defaults.compatibility_date =\n    nitro.options.compatibilityDate.cloudflare || nitro.options.compatibilityDate.default;\n\n  if (cfTarget === \"pages\") {\n    // Pages\n    overrides.pages_build_output_dir = relative(wranglerConfigDir, nitro.options.output.dir);\n  } else {\n    // Modules\n    overrides.main = relative(wranglerConfigDir, join(nitro.options.output.serverDir, \"index.mjs\"));\n    overrides.assets = {\n      binding: \"ASSETS\",\n      directory: relative(\n        wranglerConfigDir,\n        resolve(\n          nitro.options.output.publicDir,\n          \"..\".repeat(nitro.options.baseURL.split(\"/\").filter(Boolean).length)\n        )\n      ),\n    };\n  }\n\n  // Read user config\n  const { config: userConfig = {} } = await readWranglerConfig(nitro);\n\n  // Nitro context config (from frameworks and modules)\n  const ctxConfig = nitro.options.cloudflare?.wrangler || {};\n\n  // Validate and warn about overrides\n  for (const key in overrides) {\n    if (key in userConfig || key in ctxConfig) {\n      nitro.logger.warn(\n        `[cloudflare] Wrangler config \\`${key}\\`${key in ctxConfig ? \"set by config or modules\" : \"\"} is overridden and will be ignored.`\n      );\n    }\n  }\n\n  // (first argument takes precedence)\n  const wranglerConfig = defu(overrides, ctxConfig, userConfig, defaults) as WranglerConfig;\n\n  // Name is required\n  if (!wranglerConfig.name) {\n    wranglerConfig.name = await generateWorkerName(nitro)!;\n    nitro.logger.info(`Using auto generated worker name: \\`${wranglerConfig.name}\\``);\n  }\n\n  // Compatibility flags\n  wranglerConfig.compatibility_flags ??= [];\n  if (\n    nitro.options.cloudflare?.nodeCompat &&\n    !wranglerConfig.compatibility_flags.includes(\"nodejs_compat\")\n  ) {\n    wranglerConfig.compatibility_flags.push(\"nodejs_compat\");\n  }\n\n  if (cfTarget === \"module\") {\n    // Avoid double bundling\n    if (wranglerConfig.no_bundle === undefined) {\n      wranglerConfig.no_bundle = true;\n    }\n\n    // Scan all server/ chunks\n    wranglerConfig.rules ??= [];\n    if (!wranglerConfig.rules.some((rule) => rule.type === \"ESModule\")) {\n      wranglerConfig.rules.push({\n        type: \"ESModule\",\n        globs: [\"**/*.mjs\", \"**/*.js\"],\n      });\n    }\n  }\n\n  // Nitro Tasks cron triggers\n  if (\n    nitro.options.experimental.tasks &&\n    Object.keys(nitro.options.scheduledTasks || {}).length > 0 &&\n    cfTarget !== \"pages\"\n  ) {\n    const schedules = Object.keys(nitro.options.scheduledTasks!);\n    wranglerConfig.triggers = defu(wranglerConfig.triggers, { crons: [] });\n    const existingCrons = new Set(wranglerConfig.triggers!.crons);\n    for (const schedule of schedules) {\n      if (!existingCrons.has(schedule)) {\n        wranglerConfig.triggers!.crons!.push(schedule);\n      }\n    }\n  }\n\n  // Write wrangler.json\n  await writeFile(wranglerConfigPath, JSON.stringify(wranglerConfig, null, 2), true);\n\n  const configPath = join(nitro.options.rootDir, \".wrangler/deploy/config.json\");\n\n  await writeFile(\n    configPath,\n    JSON.stringify({\n      configPath: relative(dirname(configPath), wranglerConfigPath),\n    }),\n    true\n  );\n}\n\nasync function generateWorkerName(nitro: Nitro) {\n  const gitConfig = await readGitConfig(nitro.options.rootDir).catch(() => undefined);\n  const gitRepo = gitConfig?.remote?.origin?.url\n    ?.replace(/\\.git$/, \"\")\n    .match(/[/:]([^/]+\\/[^/]+)$/)?.[1];\n  const pkgJSON = await readPackageJSON(nitro.options.rootDir).catch(() => undefined);\n  const pkgName = pkgJSON?.name;\n  const subpath = relative(nitro.options.workspaceDir, nitro.options.rootDir);\n  return `${gitRepo || pkgName}/${subpath}`\n    .toLowerCase()\n    .replace(/[^a-zA-Z0-9-]/g, \"-\")\n    .replace(/-$/, \"\");\n}\n"
  },
  {
    "path": "src/presets/cloudflare/wrangler/_utils.ts",
    "content": "// Extracted from @types/yargs\ntype PascalCase<S extends string> = string extends S\n  ? string\n  : S extends `${infer T}-${infer U}`\n    ? `${Capitalize<T>}${PascalCase<U>}`\n    : Capitalize<S>;\n\ntype CamelCase<S extends string> = string extends S\n  ? string\n  : S extends `${infer T}-${infer U}`\n    ? `${T}${PascalCase<U>}`\n    : S;\n\nexport type CamelCaseKey<K extends PropertyKey> = K extends string ? Exclude<CamelCase<K>, \"\"> : K;\n"
  },
  {
    "path": "src/presets/cloudflare/wrangler/config.ts",
    "content": "/**\n * Copyright (c) 2020 Cloudflare, Inc. <wrangler@cloudflare.com>\n * https://github.com/cloudflare/workers-sdk/blob/main/LICENSE-MIT\n * https://github.com/cloudflare/workers-sdk/blob/main/LICENSE-APACHE\n *\n * Source: https://github.com/cloudflare/workers-sdk/blob/main/packages/wrangler/src/config/config.ts\n */\n\nimport type { Environment, RawEnvironment } from \"./environment.ts\";\nimport type { CamelCaseKey } from \"./_utils.ts\";\n\n/**\n * This is the static type definition for the configuration object.\n *\n * It reflects a normalized and validated version of the configuration that you can write in a Wrangler configuration file,\n * and optionally augment with arguments passed directly to wrangler.\n *\n * For more information about the configuration object, see the\n * documentation at https://developers.cloudflare.com/workers/cli-wrangler/configuration\n *\n * Notes:\n *\n * - Fields that are only specified in `ConfigFields` and not `Environment` can only appear\n * in the top level config and should not appear in any environments.\n * - Fields that are specified in `PagesConfigFields` are only relevant for Pages projects\n * - All top level fields in config and environments are optional in the Wrangler configuration file.\n *\n * Legend for the annotations:\n *\n * - `@breaking`: the deprecation/optionality is a breaking change from Wrangler v1.\n * - `@todo`: there's more work to be done (with details attached).\n */\nexport type Config = ComputedFields & ConfigFields<DevConfig> & PagesConfigFields & Environment;\n\nexport type RawConfig = Partial<ConfigFields<RawDevConfig>> &\n  PagesConfigFields &\n  RawEnvironment &\n  DeprecatedConfigFields &\n  EnvironmentMap & { $schema?: string };\n\nexport interface ComputedFields {\n  /** The path to the Wrangler configuration file (if any, and possibly redirected from the user Wrangler configuration) used to create this configuration. */\n  configPath: string | undefined;\n  /** The path to the user's Wrangler configuration file (if any), which may have been redirected to another file that used to create this configuration. */\n  userConfigPath: string | undefined;\n  /**\n   * The original top level name for the Worker in the raw configuration.\n   *\n   * When a raw configuration has been flattened to a single environment the worker name may have been replaced or transformed.\n   * It can be useful to know what the top-level name was before the flattening.\n   */\n  topLevelName: string | undefined;\n}\n\nexport interface ConfigFields<Dev extends RawDevConfig> {\n  /**\n   * A boolean to enable \"legacy\" style wrangler environments (from Wrangler v1).\n   * These have been superseded by Services, but there may be projects that won't\n   * (or can't) use them. If you're using a legacy environment, you can set this\n   * to `true` to enable it.\n   */\n  legacy_env: boolean;\n\n  /**\n   * Whether Wrangler should send usage metrics to Cloudflare for this project.\n   *\n   * When defined this will override any user settings.\n   * Otherwise, Wrangler will use the user's preference.\n   */\n  send_metrics: boolean | undefined;\n\n  /**\n   * Options to configure the development server that your worker will use.\n   */\n  dev: Dev;\n\n  /**\n   * The definition of a Worker Site, a feature that lets you upload\n   * static assets with your Worker.\n   *\n   * More details at https://developers.cloudflare.com/workers/platform/sites\n   */\n  site:\n    | {\n        /**\n         * The directory containing your static assets.\n         *\n         * It must be a path relative to your Wrangler configuration file.\n         * Example: bucket = \"./public\"\n         *\n         * If there is a `site` field then it must contain this `bucket` field.\n         */\n        bucket: string;\n\n        /**\n         * The location of your Worker script.\n         *\n         * @deprecated DO NOT use this (it's a holdover from Wrangler v1.x). Either use the top level `main` field, or pass the path to your entry file as a command line argument.\n         * @breaking\n         */\n        \"entry-point\"?: string;\n\n        /**\n         * An exclusive list of .gitignore-style patterns that match file\n         * or directory names from your bucket location. Only matched\n         * items will be uploaded. Example: include = [\"upload_dir\"]\n         *\n         * @optional\n         * @default []\n         */\n        include?: string[];\n\n        /**\n         * A list of .gitignore-style patterns that match files or\n         * directories in your bucket that should be excluded from\n         * uploads. Example: exclude = [\"ignore_dir\"]\n         *\n         * @optional\n         * @default []\n         */\n        exclude?: string[];\n      }\n    | undefined;\n\n  /**\n   * Old behaviour of serving a folder of static assets with your Worker,\n   * without any additional code.\n   * This can either be a string, or an object with additional config\n   * fields.\n   * Will be deprecated in the near future in favor of `assets`.\n   */\n  legacy_assets:\n    | {\n        bucket: string;\n        include: string[];\n        exclude: string[];\n        browser_TTL: number | undefined;\n        serve_single_page_app: boolean;\n      }\n    | string\n    | undefined;\n\n  /**\n   * A list of wasm modules that your worker should be bound to. This is\n   * the \"legacy\" way of binding to a wasm module. ES module workers should\n   * do proper module imports.\n   */\n  wasm_modules:\n    | {\n        [key: string]: string;\n      }\n    | undefined;\n\n  /**\n   * A list of text files that your worker should be bound to. This is\n   * the \"legacy\" way of binding to a text file. ES module workers should\n   * do proper module imports.\n   */\n  text_blobs:\n    | {\n        [key: string]: string;\n      }\n    | undefined;\n\n  /**\n   * A list of data files that your worker should be bound to. This is\n   * the \"legacy\" way of binding to a data file. ES module workers should\n   * do proper module imports.\n   */\n  data_blobs:\n    | {\n        [key: string]: string;\n      }\n    | undefined;\n\n  /**\n   * A map of module aliases. Lets you swap out a module for any others.\n   * Corresponds with esbuild's `alias` config\n   */\n  alias: { [key: string]: string } | undefined;\n\n  /**\n   * By default, the Wrangler configuration file is the source of truth for your environment configuration, like a terraform file.\n   *\n   * If you change your vars in the dashboard, wrangler *will* override/delete them on its next deploy.\n   *\n   * If you want to keep your dashboard vars when wrangler deploys, set this field to true.\n   *\n   * @default false\n   * @nonInheritable\n   */\n  keep_vars?: boolean;\n}\n\n// Pages-specific configuration fields\ninterface PagesConfigFields {\n  /**\n   * The directory of static assets to serve.\n   *\n   * The presence of this field in a Wrangler configuration file indicates a Pages project,\n   * and will prompt the handling of the configuration file according to the\n   * Pages-specific validation rules.\n   */\n  pages_build_output_dir?: string;\n}\n\nexport interface DevConfig {\n  /**\n   * IP address for the local dev server to listen on,\n   *\n   * @default localhost\n   */\n  ip: string;\n\n  /**\n   * Port for the local dev server to listen on\n   *\n   * @default 8787\n   */\n  port: number | undefined;\n\n  /**\n   * Port for the local dev server's inspector to listen on\n   *\n   * @default 9229\n   */\n  inspector_port: number | undefined;\n\n  /**\n   * Protocol that local wrangler dev server listens to requests on.\n   *\n   * @default http\n   */\n  local_protocol: \"http\" | \"https\";\n\n  /**\n   * Protocol that wrangler dev forwards requests on\n   *\n   * Setting this to `http` is not currently implemented for remote mode.\n   * See https://github.com/cloudflare/workers-sdk/issues/583\n   *\n   * @default https\n   */\n  upstream_protocol: \"https\" | \"http\";\n\n  /**\n   * Host to forward requests to, defaults to the host of the first route of project\n   */\n  host: string | undefined;\n}\n\nexport type RawDevConfig = Partial<DevConfig>;\n\ninterface DeprecatedConfigFields {\n  /**\n   * The project \"type\". A holdover from Wrangler v1.x.\n   * Valid values were \"webpack\", \"javascript\", and \"rust\".\n   *\n   * @deprecated DO NOT USE THIS. Most common features now work out of the box with wrangler, including modules, jsx, typescript, etc. If you need anything more, use a custom build.\n   * @breaking\n   */\n  type?: \"webpack\" | \"javascript\" | \"rust\";\n\n  /**\n   * Path to the webpack config to use when building your worker.\n   * A holdover from Wrangler v1.x, used with `type: \"webpack\"`.\n   *\n   * @deprecated DO NOT USE THIS. Most common features now work out of the box with wrangler, including modules, jsx, typescript, etc. If you need anything more, use a custom build.\n   * @breaking\n   */\n  webpack_config?: string;\n\n  /**\n   * Configuration only used by a standalone use of the miniflare binary.\n   * @deprecated\n   */\n  miniflare?: unknown;\n}\n\ninterface EnvironmentMap {\n  /**\n   * The `env` section defines overrides for the configuration for different environments.\n   *\n   * All environment fields can be specified at the top level of the config indicating the default environment settings.\n   *\n   * - Some fields are inherited and overridable in each environment.\n   * - But some are not inherited and must be explicitly specified in every environment, if they are specified at the top level.\n   *\n   * For more information, see the documentation at https://developers.cloudflare.com/workers/cli-wrangler/configuration#environments\n   *\n   * @default {}\n   */\n  env?: {\n    [envName: string]: RawEnvironment;\n  };\n}\n\n// API dev only passes in camel-cased versions of keys, so ensure\n// only camel-cased keys are used\nexport type OnlyCamelCase<T = Record<string, never>> = {\n  [key in keyof T as CamelCaseKey<key>]: T[key];\n};\n"
  },
  {
    "path": "src/presets/cloudflare/wrangler/environment.ts",
    "content": "/**\n * Copyright (c) 2020 Cloudflare, Inc. <wrangler@cloudflare.com>\n * https://github.com/cloudflare/workers-sdk/blob/main/LICENSE-MIT\n * https://github.com/cloudflare/workers-sdk/blob/main/LICENSE-APACHE\n *\n * Source: https://github.com/cloudflare/workers-sdk/blob/main/packages/wrangler/src/config/environment.ts\n */\n\n/**\n * The `Environment` interface declares all the configuration fields that\n * can be specified for an environment.\n *\n * This could be the top-level default environment, or a specific named environment.\n */\nexport interface Environment extends EnvironmentInheritable, EnvironmentNonInheritable {}\n\ntype SimpleRoute = string;\nexport type ZoneIdRoute = {\n  pattern: string;\n  zone_id: string;\n  custom_domain?: boolean;\n};\nexport type ZoneNameRoute = {\n  pattern: string;\n  zone_name: string;\n  custom_domain?: boolean;\n};\nexport type CustomDomainRoute = { pattern: string; custom_domain: boolean };\nexport type Route = SimpleRoute | ZoneIdRoute | ZoneNameRoute | CustomDomainRoute;\n\n/**\n * Configuration in wrangler for Cloudchamber\n */\nexport type CloudchamberConfig = {\n  image?: string;\n  location?: string;\n  instance_type?: \"dev\" | \"basic\" | \"standard\";\n  vcpu?: number;\n  memory?: string;\n  ipv4?: boolean;\n};\n\n/**\n * Configuration for a container application\n */\nexport type ContainerApp = {\n  // TODO: fill out the entire type\n\n  /**\n   * Name of the application\n   * @optional Defaults to `worker_name-class_name` if not specified.\n   */\n  name?: string;\n\n  /**\n   * Number of application instances\n   * @deprecated\n   * @hidden\n   */\n  instances?: number;\n\n  /**\n   * Number of maximum application instances.\n   * @optional\n   */\n  max_instances?: number;\n\n  /**\n   * The path to a Dockerfile, or an image URI for the Cloudflare registry.\n   */\n  image: string;\n\n  /**\n   * Build context of the application.\n   * @optional - defaults to the directory of `image`.\n   */\n  image_build_context?: string;\n\n  /**\n   * Image variables to be passed along the image at build time.\n   * @optional\n   */\n  image_vars?: Record<string, string>;\n\n  /**\n   * The class name of the Durable Object the container is connected to.\n   */\n  class_name: string;\n\n  /**\n   * The scheduling policy of the application\n   * @optional\n   * @default \"default\"\n   */\n  scheduling_policy?: \"regional\" | \"moon\" | \"default\";\n\n  /**\n   * The instance type to be used for the container. This sets preconfigured options for vcpu and memory\n   * @optional\n   */\n  instance_type?: \"dev\" | \"basic\" | \"standard\";\n\n  /**\n   * @deprecated Use top level `containers` fields instead.\n   * `configuration.image` should be `image`\n   * `configuration.disk` should be set via `instance_type`\n   * @hidden\n   */\n  configuration?: {\n    image?: string;\n    labels?: { name: string; value: string }[];\n    secrets?: { name: string; type: \"env\"; secret: string }[];\n    disk?: { size: string };\n  };\n\n  /**\n   * Scheduling constraints\n   * @hidden\n   */\n  constraints?: {\n    regions?: string[];\n    cities?: string[];\n    tier?: number;\n  };\n\n  /**\n   * @deprecated use the `class_name` field instead.\n   * @hidden\n   */\n  durable_objects?: {\n    namespace_id: string;\n  };\n\n  /**\n   * How a rollout should be done, defining the size of it\n   * @optional\n   * @default 25\n   * */\n  rollout_step_percentage?: number;\n\n  /**\n   * How a rollout should be created. It supports the following modes:\n   *  - full_auto: The container application will be rolled out fully automatically.\n   *  - none: The container application won't have a roll out or update.\n   *  - manual: The container application will be rollout fully by manually actioning progress steps.\n   * @optional\n   * @default \"full_auto\"\n   */\n  rollout_kind?: \"full_auto\" | \"none\" | \"full_manual\";\n};\n\n/**\n * Configuration in wrangler for Durable Object Migrations\n */\nexport type DurableObjectMigration = {\n  /** A unique identifier for this migration. */\n  tag: string;\n  /** The new Durable Objects being defined. */\n  new_classes?: string[];\n  /** The new SQLite Durable Objects being defined. */\n  new_sqlite_classes?: string[];\n  /** The Durable Objects being renamed. */\n  renamed_classes?: {\n    from: string;\n    to: string;\n  }[];\n  /** The Durable Objects being removed. */\n  deleted_classes?: string[];\n};\n\n/**\n * The `EnvironmentInheritable` interface declares all the configuration fields for an environment\n * that can be inherited (and overridden) from the top-level environment.\n */\ninterface EnvironmentInheritable {\n  /**\n   * The name of your Worker. Alphanumeric + dashes only.\n   *\n   * @inheritable\n   */\n  name: string | undefined;\n\n  /**\n   * This is the ID of the account associated with your zone.\n   * You might have more than one account, so make sure to use\n   * the ID of the account associated with the zone/route you\n   * provide, if you provide one. It can also be specified through\n   * the CLOUDFLARE_ACCOUNT_ID environment variable.\n   *\n   * @inheritable\n   */\n  account_id: string | undefined;\n\n  /**\n   * A date in the form yyyy-mm-dd, which will be used to determine\n   * which version of the Workers runtime is used.\n   *\n   * More details at https://developers.cloudflare.com/workers/configuration/compatibility-dates\n   *\n   * @inheritable\n   */\n  compatibility_date: string | undefined;\n\n  /**\n   * A list of flags that enable features from upcoming features of\n   * the Workers runtime, usually used together with compatibility_date.\n   *\n   * More details at https://developers.cloudflare.com/workers/configuration/compatibility-flags/\n   *\n   * @default []\n   * @inheritable\n   */\n  compatibility_flags: string[];\n\n  /**\n   * The entrypoint/path to the JavaScript file that will be executed.\n   *\n   * @inheritable\n   */\n  main: string | undefined;\n\n  /**\n   * If true then Wrangler will traverse the file tree below `base_dir`;\n   * Any files that match `rules` will be included in the deployed Worker.\n   * Defaults to true if `no_bundle` is true, otherwise false.\n   *\n   * @inheritable\n   */\n  find_additional_modules: boolean | undefined;\n\n  /**\n   * Determines whether Wrangler will preserve bundled file names.\n   * Defaults to false.\n   * If left unset, files will be named using the pattern ${fileHash}-${basename},\n   * for example, `34de60b44167af5c5a709e62a4e20c4f18c9e3b6-favicon.ico`.\n   *\n   * @inheritable\n   */\n  preserve_file_names: boolean | undefined;\n\n  /**\n   * The directory in which module rules should be evaluated when including additional files into a Worker deployment.\n   * This defaults to the directory containing the `main` entry point of the Worker if not specified.\n   *\n   * @inheritable\n   */\n  base_dir: string | undefined;\n\n  // Carmen according to our tests the default is undefined\n  // warning: you must force \"workers_dev: true\" in tests to match expected behavior\n  /**\n   * Whether we use <name>.<subdomain>.workers.dev to\n   * test and deploy your Worker.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#workersdev\n   *\n   * @default true\n   * @breaking\n   * @inheritable\n   */\n\n  workers_dev: boolean | undefined;\n\n  /**\n   * Whether we use <version>-<name>.<subdomain>.workers.dev to\n   * serve Preview URLs for your Worker.\n   *\n   * @default true\n   * @inheritable\n   */\n  preview_urls: boolean | undefined;\n\n  /**\n   * A list of routes that your Worker should be published to.\n   * Only one of `routes` or `route` is required.\n   *\n   * Only required when workers_dev is false, and there's no scheduled Worker (see `triggers`)\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#types-of-routes\n   *\n   * @inheritable\n   */\n  routes: Route[] | undefined;\n\n  /**\n   * A route that your Worker should be published to. Literally\n   * the same as routes, but only one.\n   * Only one of `routes` or `route` is required.\n   *\n   * Only required when workers_dev is false, and there's no scheduled Worker\n   *\n   * @inheritable\n   */\n  route: Route | undefined;\n\n  /**\n   * Path to a custom tsconfig\n   *\n   * @inheritable\n   */\n  tsconfig: string | undefined;\n\n  /**\n   * The function to use to replace jsx syntax.\n   *\n   * @default \"React.createElement\"\n   * @inheritable\n   */\n  jsx_factory: string;\n\n  /**\n   * The function to use to replace jsx fragment syntax.\n   *\n   * @default \"React.Fragment\"\n   * @inheritable\n   */\n  jsx_fragment: string;\n\n  /**\n   * A list of migrations that should be uploaded with your Worker.\n   *\n   * These define changes in your Durable Object declarations.\n   *\n   * More details at https://developers.cloudflare.com/workers/learning/using-durable-objects#configuring-durable-object-classes-with-migrations\n   *\n   * @default []\n   * @inheritable\n   */\n  migrations: DurableObjectMigration[];\n\n  /**\n   * \"Cron\" definitions to trigger a Worker's \"scheduled\" function.\n   *\n   * Lets you call Workers periodically, much like a cron job.\n   *\n   * More details here https://developers.cloudflare.com/workers/platform/cron-triggers\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#triggers\n   *\n   * @default {crons: undefined}\n   * @inheritable\n   */\n  triggers: { crons: string[] | undefined };\n\n  /**\n   * Specify limits for runtime behavior.\n   * Only supported for the \"standard\" Usage Model\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#limits\n   *\n   * @inheritable\n   */\n  limits: UserLimits | undefined;\n\n  /**\n   * An ordered list of rules that define which modules to import,\n   * and what type to import them as. You will need to specify rules\n   * to use Text, Data, and CompiledWasm modules, or when you wish to\n   * have a .js file be treated as an ESModule instead of CommonJS.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#bundling\n   *\n   * @inheritable\n   */\n  rules: Rule[];\n\n  /**\n   * Configures a custom build step to be run by Wrangler when building your Worker.\n   *\n   * Refer to the [custom builds documentation](https://developers.cloudflare.com/workers/cli-wrangler/configuration#build)\n   * for more details.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#custom-builds\n   *\n   * @default {watch_dir:\"./src\"}\n   */\n  build: {\n    /** The command used to build your Worker. On Linux and macOS, the command is executed in the `sh` shell and the `cmd` shell for Windows. The `&&` and `||` shell operators may be used. */\n    command?: string;\n    /** The directory in which the command is executed. */\n    cwd?: string;\n    /** The directory to watch for changes while using wrangler dev, defaults to the current working directory */\n    watch_dir?: string | string[];\n  };\n\n  /**\n   * Skip internal build steps and directly deploy script\n   * @inheritable\n   */\n  no_bundle: boolean | undefined;\n\n  /**\n   * Minify the script before uploading.\n   * @inheritable\n   */\n  minify: boolean | undefined;\n\n  /**\n   * Set the `name` property to the original name for functions and classes renamed during minification.\n   *\n   * See https://esbuild.github.io/api/#keep-names\n   *\n   * @default true\n   * @inheritable\n   */\n  keep_names: boolean | undefined;\n\n  /**\n   * Designates this Worker as an internal-only \"first-party\" Worker.\n   *\n   * @inheritable\n   */\n  first_party_worker: boolean | undefined;\n\n  /**\n   * List of bindings that you will send to logfwdr\n   *\n   * @default {bindings:[]}\n   * @inheritable\n   */\n  logfwdr: {\n    bindings: {\n      /** The binding name used to refer to logfwdr */\n      name: string;\n      /** The destination for this logged message */\n      destination: string;\n    }[];\n  };\n\n  /**\n   * Send Trace Events from this Worker to Workers Logpush.\n   *\n   * This will not configure a corresponding Logpush job automatically.\n   *\n   * For more information about Workers Logpush, see:\n   * https://blog.cloudflare.com/logpush-for-workers/\n   *\n   * @inheritable\n   */\n  logpush: boolean | undefined;\n\n  /**\n   * Include source maps when uploading this worker.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#source-maps\n   *\n   * @inheritable\n   */\n  upload_source_maps: boolean | undefined;\n\n  /**\n   * Specify how the Worker should be located to minimize round-trip time.\n   *\n   * More details: https://developers.cloudflare.com/workers/platform/smart-placement/\n   *\n   * @inheritable\n   */\n  placement: { mode: \"off\" | \"smart\"; hint?: string } | undefined;\n\n  /**\n   * Specify the directory of static assets to deploy/serve\n   *\n   * More details at https://developers.cloudflare.com/workers/frameworks/\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#assets\n   *\n   * @inheritable\n   */\n  assets: Assets | undefined;\n\n  /**\n   * Specify the observability behavior of the Worker.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#observability\n   *\n   * @inheritable\n   */\n  observability: Observability | undefined;\n\n  /**\n   * Specify the compliance region mode of the Worker.\n   *\n   * Although if the user does not specify a compliance region, the default is `public`,\n   * it can be set to `undefined` in configuration to delegate to the CLOUDFLARE_COMPLIANCE_REGION environment variable.\n   */\n  compliance_region: \"public\" | \"fedramp_high\" | undefined;\n}\n\nexport type DurableObjectBindings = {\n  /** The name of the binding used to refer to the Durable Object */\n  name: string;\n  /** The exported class name of the Durable Object */\n  class_name: string;\n  /** The script where the Durable Object is defined (if it's external to this Worker) */\n  script_name?: string;\n  /** The service environment of the script_name to bind to */\n  environment?: string;\n}[];\n\nexport type WorkflowBinding = {\n  /** The name of the binding used to refer to the Workflow */\n  binding: string;\n  /** The name of the Workflow */\n  name: string;\n  /** The exported class name of the Workflow */\n  class_name: string;\n  /** The script where the Workflow is defined (if it's external to this Worker) */\n  script_name?: string;\n  /** Whether the Workflow should be remote or not (only available under `--x-remote-bindings`) */\n  experimental_remote?: boolean;\n};\n\n/**\n * The `EnvironmentNonInheritable` interface declares all the configuration fields for an environment\n * that cannot be inherited from the top-level environment, and must be defined specifically.\n *\n * If any of these fields are defined at the top-level then they should also be specifically defined\n * for each named environment.\n */\nexport interface EnvironmentNonInheritable {\n  /**\n   * A map of values to substitute when deploying your Worker.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  define: Record<string, string>;\n  /**\n   * A map of environment variables to set when deploying your Worker.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  vars: Record<string, unknown>;\n\n  /**\n   * A list of durable objects that your Worker should be bound to.\n   *\n   * For more information about Durable Objects, see the documentation at\n   * https://developers.cloudflare.com/workers/learning/using-durable-objects\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects\n   *\n   * @default {bindings:[]}\n   * @nonInheritable\n   */\n  durable_objects: {\n    bindings: DurableObjectBindings;\n  };\n\n  /**\n   * A list of workflows that your Worker should be bound to.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default []\n   * @nonInheritable\n   */\n  workflows: WorkflowBinding[];\n\n  /**\n   * Cloudchamber configuration\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  cloudchamber: CloudchamberConfig;\n\n  /**\n   * Container related configuration\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default []\n   * @nonInheritable\n   */\n  containers?: ContainerApp[];\n\n  /**\n   * These specify any Workers KV Namespaces you want to\n   * access from inside your Worker.\n   *\n   * To learn more about KV Namespaces,\n   * see the documentation at https://developers.cloudflare.com/workers/learning/how-kv-works\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces\n   *\n   * @default []\n   * @nonInheritable\n   */\n  kv_namespaces: {\n    /** The binding name used to refer to the KV Namespace */\n    binding: string;\n    /** The ID of the KV namespace */\n    id?: string;\n    /** The ID of the KV namespace used during `wrangler dev` */\n    preview_id?: string;\n    /** Whether the KV namespace should be remote or not (only available under `--x-remote-bindings`) */\n    experimental_remote?: boolean;\n  }[];\n\n  /**\n   * These specify bindings to send email from inside your Worker.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#email-bindings\n   *\n   * @default []\n   * @nonInheritable\n   */\n  send_email: {\n    /** The binding name used to refer to the this binding */\n    name: string;\n    /** If this binding should be restricted to a specific verified address */\n    destination_address?: string;\n    /** If this binding should be restricted to a set of verified addresses */\n    allowed_destination_addresses?: string[];\n  }[];\n\n  /**\n   * Specifies Queues that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#queues\n   *\n   * @default {consumers:[],producers:[]}\n   * @nonInheritable\n   */\n  queues: {\n    /** Producer bindings */\n    producers?: {\n      /** The binding name used to refer to the Queue in the Worker. */\n      binding: string;\n\n      /** The name of this Queue. */\n      queue: string;\n\n      /** The number of seconds to wait before delivering a message */\n      delivery_delay?: number;\n\n      /** Whether the Queue producer should be remote or not (only available under `--x-remote-bindings`) */\n      experimental_remote?: boolean;\n    }[];\n\n    /** Consumer configuration */\n    consumers?: {\n      /** The name of the queue from which this consumer should consume. */\n      queue: string;\n\n      /** The consumer type, e.g., worker, http-pull, r2-bucket, etc. Default is worker. */\n      type?: string;\n\n      /** The maximum number of messages per batch */\n      max_batch_size?: number;\n\n      /** The maximum number of seconds to wait to fill a batch with messages. */\n      max_batch_timeout?: number;\n\n      /** The maximum number of retries for each message. */\n      max_retries?: number;\n\n      /** The queue to send messages that failed to be consumed. */\n      dead_letter_queue?: string;\n\n      /** The maximum number of concurrent consumer Worker invocations. Leaving this unset will allow your consumer to scale to the maximum concurrency needed to keep up with the message backlog. */\n      max_concurrency?: number | null;\n\n      /** The number of milliseconds to wait for pulled messages to become visible again */\n      visibility_timeout_ms?: number;\n\n      /** The number of seconds to wait before retrying a message */\n      retry_delay?: number;\n    }[];\n  };\n\n  /**\n   * Specifies R2 buckets that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets\n   *\n   * @default []\n   * @nonInheritable\n   */\n  r2_buckets: {\n    /** The binding name used to refer to the R2 bucket in the Worker. */\n    binding: string;\n    /** The name of this R2 bucket at the edge. */\n    bucket_name?: string;\n    /** The preview name of this R2 bucket at the edge. */\n    preview_bucket_name?: string;\n    /** The jurisdiction that the bucket exists in. Default if not present. */\n    jurisdiction?: string;\n    /** Whether the R2 bucket should be remote or not (only available under `--x-remote-bindings`) */\n    experimental_remote?: boolean;\n  }[];\n\n  /**\n   * Specifies D1 databases that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases\n   *\n   * @default []\n   * @nonInheritable\n   */\n  d1_databases: {\n    /** The binding name used to refer to the D1 database in the Worker. */\n    binding: string;\n    /** The name of this D1 database. */\n    database_name?: string;\n    /** The UUID of this D1 database (not required). */\n    database_id?: string;\n    /** The UUID of this D1 database for Wrangler Dev (if specified). */\n    preview_database_id?: string;\n    /** The name of the migrations table for this D1 database (defaults to 'd1_migrations'). */\n    migrations_table?: string;\n    /** The path to the directory of migrations for this D1 database (defaults to './migrations'). */\n    migrations_dir?: string;\n    /** Internal use only. */\n    database_internal_env?: string;\n    /** Whether the D1 database should be remote or not (only available under `--x-remote-bindings`) */\n    experimental_remote?: boolean;\n  }[];\n\n  /**\n   * Specifies Vectorize indexes that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes\n   *\n   * @default []\n   * @nonInheritable\n   */\n  vectorize: {\n    /** The binding name used to refer to the Vectorize index in the Worker. */\n    binding: string;\n    /** The name of the index. */\n    index_name: string;\n    /** Whether the Vectorize index should be remote or not (only available under `--x-remote-bindings`) */\n    experimental_remote?: boolean;\n  }[];\n\n  /**\n   * Specifies Hyperdrive configs that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive\n   *\n   * @default []\n   * @nonInheritable\n   */\n  hyperdrive: {\n    /** The binding name used to refer to the project in the Worker. */\n    binding: string;\n    /** The id of the database. */\n    id: string;\n    /** The local database connection string for `wrangler dev` */\n    localConnectionString?: string;\n  }[];\n\n  /**\n   * Specifies service bindings (Worker-to-Worker) that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings\n   *\n   * @default []\n   * @nonInheritable\n   */\n  services:\n    | {\n        /** The binding name used to refer to the bound service. */\n        binding: string;\n        /** The name of the service. */\n        service: string;\n        /** The environment of the service (e.g. production, staging, etc). */\n        environment?: string;\n        /** Optionally, the entrypoint (named export) of the service to bind to. */\n        entrypoint?: string;\n        /** Optional properties that will be made available to the service via ctx.props. */\n        props?: Record<string, unknown>;\n        /** Whether the service binding should be remote or not (only available under `--x-remote-bindings`) */\n        experimental_remote?: boolean;\n      }[]\n    | undefined;\n\n  /**\n   * Specifies analytics engine datasets that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets\n   *\n   * @default []\n   * @nonInheritable\n   */\n  analytics_engine_datasets: {\n    /** The binding name used to refer to the dataset in the Worker. */\n    binding: string;\n    /** The name of this dataset to write to. */\n    dataset?: string;\n  }[];\n\n  /**\n   * A browser that will be usable from the Worker.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  browser:\n    | {\n        binding: string;\n        /** Whether the Browser binding should be remote or not (only available under `--x-remote-bindings`) */\n        experimental_remote?: boolean;\n      }\n    | undefined;\n\n  /**\n   * Binding to the AI project.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  ai:\n    | {\n        binding: string;\n        staging?: boolean;\n        /** Whether the AI binding should be remote or not (only available under `--x-remote-bindings`) */\n        experimental_remote?: boolean;\n      }\n    | undefined;\n\n  /**\n   * Binding to Cloudflare Images\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#images\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  images:\n    | {\n        binding: string;\n        /** Whether the Images binding should be remote or not (only available under `--x-remote-bindings`) */\n        experimental_remote?: boolean;\n      }\n    | undefined;\n\n  /**\n   * Binding to the Worker Version's metadata\n   */\n  version_metadata:\n    | {\n        binding: string;\n      }\n    | undefined;\n\n  /**\n   * \"Unsafe\" tables for features that aren't directly supported by wrangler.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default {}\n   * @nonInheritable\n   */\n  unsafe: {\n    /**\n     * A set of bindings that should be put into a Worker's upload metadata without changes. These\n     * can be used to implement bindings for features that haven't released and aren't supported\n     * directly by wrangler or miniflare.\n     */\n    bindings?: {\n      name: string;\n      type: string;\n      [key: string]: unknown;\n    }[];\n\n    /**\n     * Arbitrary key/value pairs that will be included in the uploaded metadata.  Values specified\n     * here will always be applied to metadata last, so can add new or override existing fields.\n     */\n    metadata?: {\n      [key: string]: unknown;\n    };\n\n    /**\n     * Used for internal capnp uploads for the Workers runtime\n     */\n    capnp?:\n      | {\n          base_path: string;\n          source_schemas: string[];\n          compiled_schema?: never;\n        }\n      | {\n          base_path?: never;\n          source_schemas?: never;\n          compiled_schema: string;\n        };\n  };\n\n  /**\n   * Specifies a list of mTLS certificates that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates\n   *\n   * @default []\n   * @nonInheritable\n   */\n  mtls_certificates: {\n    /** The binding name used to refer to the certificate in the Worker */\n    binding: string;\n    /** The uuid of the uploaded mTLS certificate */\n    certificate_id: string;\n    /** Whether the mtls fetcher should be remote or not (only available under `--x-remote-bindings`) */\n    experimental_remote?: boolean;\n  }[];\n\n  /**\n   * Specifies a list of Tail Workers that are bound to this Worker environment\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default []\n   * @nonInheritable\n   */\n  tail_consumers?: TailConsumer[];\n\n  /**\n   * Specifies namespace bindings that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * For reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms\n   *\n   * @default []\n   * @nonInheritable\n   */\n  dispatch_namespaces: {\n    /** The binding name used to refer to the bound service. */\n    binding: string;\n    /** The namespace to bind to. */\n    namespace: string;\n    /** Details about the outbound Worker which will handle outbound requests from your namespace */\n    outbound?: DispatchNamespaceOutbound;\n    /** Whether the Dispatch Namespace should be remote or not (only available under `--x-remote-bindings`) */\n    experimental_remote?: boolean;\n  }[];\n\n  /**\n   * Specifies list of Pipelines bound to this Worker environment\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default []\n   * @nonInheritable\n   */\n  pipelines: {\n    /** The binding name used to refer to the bound service. */\n    binding: string;\n\n    /** Name of the Pipeline to bind */\n    pipeline: string;\n  }[];\n\n  /**\n   * Specifies Secret Store bindings that are bound to this Worker environment.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default []\n   * @nonInheritable\n   */\n  secrets_store_secrets: {\n    /** The binding name used to refer to the bound service. */\n    binding: string;\n\n    /** Id of the secret store */\n    store_id: string;\n\n    /** Name of the secret */\n    secret_name: string;\n  }[];\n\n  /**\n   * **DO NOT USE**. Hello World Binding Config to serve as an explanatory example.\n   *\n   * NOTE: This field is not automatically inherited from the top level environment,\n   * and so must be specified in every named environment.\n   *\n   * @default []\n   * @nonInheritable\n   */\n  unsafe_hello_world: {\n    /** The binding name used to refer to the bound service. */\n    binding: string;\n\n    /** Whether the timer is enabled */\n    enable_timer?: boolean;\n  }[];\n}\n\n/**\n * The raw environment configuration that we read from the config file.\n *\n * All the properties are optional, and will be replaced with defaults in the configuration that\n * is used in the rest of the codebase.\n */\nexport type RawEnvironment = Partial<Environment>;\n\n/**\n * A bundling resolver rule, defining the modules type for paths that match the specified globs.\n */\nexport type Rule = {\n  type: ConfigModuleRuleType;\n  globs: string[];\n  fallthrough?: boolean;\n};\n\n/**\n * The possible types for a `Rule`.\n */\nexport type ConfigModuleRuleType =\n  | \"ESModule\"\n  | \"CommonJS\"\n  | \"CompiledWasm\"\n  | \"Text\"\n  | \"Data\"\n  | \"PythonModule\"\n  | \"PythonRequirement\";\n\nexport type TailConsumer = {\n  /** The name of the service tail events will be forwarded to. */\n  service: string;\n  /** (Optional) The environment of the service. */\n  environment?: string;\n};\n\nexport interface DispatchNamespaceOutbound {\n  /** Name of the service handling the outbound requests */\n  service: string;\n  /** (Optional) Name of the environment handling the outbound requests. */\n  environment?: string;\n  /** (Optional) List of parameter names, for sending context from your dispatch Worker to the outbound handler */\n  parameters?: string[];\n}\n\nexport interface UserLimits {\n  /** Maximum allowed CPU time for a Worker's invocation in milliseconds */\n  cpu_ms: number;\n}\n\nexport type Assets = {\n  /** Absolute path to assets directory */\n  directory?: string;\n  /** Name of `env` binding property in the User Worker. */\n  binding?: string;\n  /** How to handle HTML requests. */\n  html_handling?: \"auto-trailing-slash\" | \"force-trailing-slash\" | \"drop-trailing-slash\" | \"none\";\n  /** How to handle requests that do not match an asset. */\n  not_found_handling?: \"single-page-application\" | \"404-page\" | \"none\";\n  /**\n   * Matches will be routed to the User Worker, and matches to negative rules will go to the Asset Worker.\n   *\n   * Can also be `true`, indicating that every request should be routed to the User Worker.\n   */\n  run_worker_first?: string[] | boolean;\n};\n\nexport interface Observability {\n  /** If observability is enabled for this Worker */\n  enabled?: boolean;\n  /** The sampling rate */\n  head_sampling_rate?: number;\n  logs?: {\n    enabled?: boolean;\n    /** The sampling rate */\n    head_sampling_rate?: number;\n    /** Set to false to disable invocation logs */\n    invocation_logs?: boolean;\n  };\n}\n\nexport type DockerConfiguration = {\n  /** Socket used by miniflare to communicate with Docker */\n  socketPath: string;\n};\n\nexport type ContainerEngine =\n  | {\n      localDocker: DockerConfiguration;\n    }\n  | string;\n"
  },
  {
    "path": "src/presets/deno/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport { resolve } from \"pathe\";\nimport { unenvDeno } from \"./unenv/preset.ts\";\nimport { builtinModules } from \"node:module\";\n\nconst denoDeploy = defineNitroPreset(\n  {\n    entry: \"./deno/runtime/deno-deploy\",\n    manifest: {\n      // https://docs.deno.com/deploy/reference/env_vars_and_contexts/#predefined-environment-variables\n      // https://docs.deno.com/deploy/classic/environment-variables/#default-environment-variables\n      deploymentId: process.env.DENO_DEPLOYMENT_ID,\n    },\n    exportConditions: [\"deno\"],\n    node: false,\n    serveStatic: \"deno\",\n    commands: {\n      preview: \"\",\n      deploy: \"cd ./ && deno run -A jsr:@deno/deployctl deploy server/index.ts\",\n    },\n    unenv: unenvDeno,\n    rollupConfig: {\n      preserveEntrySignatures: false,\n      external: (id) => id.startsWith(\"https://\") || id.startsWith(\"node:\"),\n      output: {\n        entryFileNames: \"index.ts\",\n        manualChunks: (id) => \"index\",\n        format: \"esm\",\n      },\n    },\n  },\n  {\n    name: \"deno-deploy\" as const,\n  }\n);\n\nconst denoServer = defineNitroPreset(\n  {\n    entry: \"./deno/runtime/deno-server\",\n    serveStatic: true,\n    exportConditions: [\"deno\"],\n    commands: {\n      preview: \"deno -A ./server/index.mjs\",\n    },\n    rollupConfig: {\n      external: (id) =>\n        id.startsWith(\"https://\") || id.startsWith(\"node:\") || builtinModules.includes(id),\n      output: {\n        hoistTransitiveImports: false,\n      },\n    },\n    hooks: {\n      async compiled(nitro) {\n        // https://docs.deno.com/runtime/fundamentals/configuration/\n        const denoJSON = {\n          tasks: {\n            start: \"deno run -A ./server/index.mjs\",\n          },\n        };\n        await writeFile(\n          resolve(nitro.options.output.dir, \"deno.json\"),\n          JSON.stringify(denoJSON, null, 2)\n        );\n      },\n    },\n  },\n  {\n    aliases: [\"deno\"],\n    name: \"deno-server\" as const,\n  }\n);\n\nexport default [denoDeploy, denoServer] as const;\n"
  },
  {
    "path": "src/presets/deno/runtime/deno-deploy.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type { ServerRequest } from \"srvx\";\nimport type { Deno as _Deno } from \"@deno/types\";\nimport wsAdapter from \"crossws/adapters/deno\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\ndeclare global {\n  var Deno: typeof _Deno;\n}\n\nconst nitroApp = useNitroApp();\n\nconst ws = import.meta._websocket ? wsAdapter({ resolve: resolveWebsocketHooks }) : undefined;\n\n// TODO: Migrate to srvx to provide request IP\nDeno.serve((denoReq: Request, info: _Deno.ServeHandlerInfo) => {\n  // srvx compatibility\n  const req = denoReq as unknown as ServerRequest;\n  req.runtime ??= { name: \"deno\" };\n  req.runtime.deno ??= { info } as any;\n  // TODO: Support remoteAddr\n\n  // https://crossws.unjs.io/adapters/deno\n  if (import.meta._websocket && req.headers.get(\"upgrade\") === \"websocket\") {\n    return ws!.handleUpgrade(req, info);\n  }\n\n  return nitroApp.fetch(req);\n});\n"
  },
  {
    "path": "src/presets/deno/runtime/deno-server.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type { ServerRequest } from \"srvx\";\nimport { serve } from \"srvx/deno\";\nimport wsAdapter from \"crossws/adapters/deno\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\nimport { trapUnhandledErrors } from \"#nitro/runtime/error/hooks\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst _parsedPort = Number.parseInt(process.env.NITRO_PORT ?? process.env.PORT ?? \"\");\nconst port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort;\n\nconst host = process.env.NITRO_HOST || process.env.HOST;\nconst cert = process.env.NITRO_SSL_CERT;\nconst key = process.env.NITRO_SSL_KEY;\n// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO\n\nconst nitroApp = useNitroApp();\n\nlet _fetch = nitroApp.fetch;\n\nif (import.meta._websocket) {\n  const { handleUpgrade } = wsAdapter({ resolve: resolveWebsocketHooks });\n  _fetch = (req: ServerRequest) => {\n    if (req.headers.get(\"upgrade\") === \"websocket\") {\n      return handleUpgrade(req, req.runtime!.deno!.info);\n    }\n    return nitroApp.fetch(req);\n  };\n}\n\nconst server = serve({\n  port,\n  hostname: host,\n  tls: cert && key ? { cert, key } : undefined,\n  fetch: _fetch,\n});\n\ntrapUnhandledErrors();\n\n// Scheduled tasks\nif (import.meta._tasks) {\n  startScheduleRunner({ waitUntil: server.waitUntil });\n}\n\nexport default {};\n"
  },
  {
    "path": "src/presets/deno/unenv/node-compat.ts",
    "content": "// Auto generated at 2025-10-05\n// Source: https://platform-node-compat.deno.dev/\n// Do not edit this file manually\n\n// prettier-ignore\nexport const builtnNodeModules = [\n  \"node:_http_agent\",\n  \"node:_http_common\", // Missing exports: freeParser, isLenient, parsers, prepareError\n  \"node:_http_outgoing\",\n  \"node:_http_server\", // Missing exports: Server, ServerResponse, httpServerPreClose, kConnectionsCheckingInterval, kServerResponse, setupConnectionsTracking, storeHTTPOptions\n  \"node:_stream_duplex\", // Missing exports: from, fromWeb, toWeb\n  \"node:_stream_passthrough\",\n  \"node:_stream_readable\", // Missing exports: ReadableState, from, fromWeb, toWeb, wrap\n  \"node:_stream_transform\",\n  \"node:_stream_writable\", // Missing exports: WritableState, fromWeb, toWeb\n  \"node:_tls_common\", // Missing exports: SecureContext, translatePeerCertificate\n  \"node:_tls_wrap\",\n  \"node:assert\", // Missing exports: Assert, CallTracker, partialDeepStrictEqual\n  \"node:assert/strict\", // Missing exports: Assert, CallTracker, partialDeepStrictEqual\n  \"node:async_hooks\",\n  \"node:buffer\", // Missing exports: File, resolveObjectURL\n  \"node:child_process\",\n  \"node:cluster\",\n  \"node:console\", // Missing exports: context, createTask\n  \"node:constants\", // Missing exports: O_DIRECT, O_NOATIME, defaultCipherList\n  \"node:crypto\", // Missing exports: argon2, argon2Sync, decapsulate, encapsulate\n  \"node:dgram\",\n  \"node:diagnostics_channel\", // Missing exports: Channel\n  \"node:dns\", // Missing exports: getDefaultResultOrder, lookupService, resolveTlsa\n  \"node:dns/promises\", // Missing exports: getDefaultResultOrder, lookupService, resolveTlsa\n  \"node:domain\",\n  \"node:events\", // Missing exports: captureRejections, getMaxListeners, init, usingDomains\n  \"node:fs\", // Missing exports: FileReadStream, FileWriteStream, Utf8Stream, fchmod, fchmodSync, fchown, fchownSync, glob, globSync, lchmod, lchmodSync, lchown, lchownSync, mkdtempDisposableSync, openAsBlob\n  \"node:fs/promises\", // Missing exports: glob, lchmod, lchown, lutimes, mkdtempDisposable, statfs\n  \"node:http\", // Missing exports: CloseEvent, MessageEvent, WebSocket, setMaxIdleHTTPParsers\n  \"node:http2\", // Missing exports: performServerHandshake\n  \"node:https\",\n  \"node:inspector\", // Missing exports: NetworkResources\n  \"node:inspector/promises\", // Missing exports: NetworkResources\n  \"node:module\", // Missing exports: SourceMap, constants, enableCompileCache, findPackageJSON, flushCompileCache, getCompileCacheDir, getSourceMapsSupport, registerHooks, runMain, setSourceMapsSupport, stripTypeScriptTypes, syncBuiltinESMExports\n  \"node:net\",\n  \"node:os\",\n  \"node:path\", // Missing exports: matchesGlob\n  \"node:path/posix\", // Missing exports: matchesGlob\n  \"node:path/win32\", // Missing exports: matchesGlob\n  \"node:perf_hooks\", // Missing exports: Performance, PerformanceMark, PerformanceMeasure, PerformanceObserverEntryList, PerformanceResourceTiming, createHistogram\n  \"node:process\", // Missing exports: availableMemory, binding, config, constrainedMemory, debugPort, domain, execve, exitCode, features, finalization, getActiveResourcesInfo, getgroups, hasUncaughtExceptionCaptureCallback, initgroups, loadEnvFile, moduleLoadList, openStdin, ppid, reallyExit, ref, release, report, resourceUsage, setSourceMapsEnabled, setUncaughtExceptionCaptureCallback, setegid, seteuid, setgid, setgroups, setuid, sourceMapsEnabled, threadCpuUsage, title, unref, uptime\n  \"node:punycode\",\n  \"node:querystring\",\n  \"node:readline\",\n  \"node:readline/promises\",\n  \"node:repl\", // Missing exports: Recoverable, isValidSyntax, writer\n  \"node:sqlite\", // Missing exports: Session, StatementSync, backup\n  \"node:stream\", // Missing exports: destroy, promises\n  \"node:stream/consumers\",\n  \"node:stream/promises\",\n  \"node:stream/web\",\n  \"node:string_decoder\",\n  \"node:sys\", // Missing exports: MIMEParams, MIMEType, diff, getCallSite, getSystemErrorMap, getSystemErrorMessage, parseEnv, setTraceSigInt, transferableAbortController, transferableAbortSignal\n  \"node:test\", // Missing exports: assert, only, skip, snapshot, todo\n  \"node:timers\",\n  \"node:timers/promises\",\n  \"node:tls\", // Missing exports: SecureContext, convertALPNProtocols, getCACertificates, setDefaultCACertificates\n  \"node:trace_events\",\n  \"node:tty\",\n  \"node:url\", // Missing exports: URLPattern, fileURLToPathBuffer\n  \"node:util\", // Missing exports: MIMEParams, MIMEType, diff, getCallSite, getSystemErrorMap, getSystemErrorMessage, parseEnv, setTraceSigInt, transferableAbortController, transferableAbortSignal\n  \"node:util/types\", // Missing exports: isExternal\n  \"node:v8\", // Missing exports: GCProfiler, getCppHeapStatistics, isStringOneByteRepresentation, promiseHooks, queryObjects, setHeapSnapshotNearHeapLimit, startupSnapshot\n  \"node:vm\",\n  \"node:wasi\",\n  \"node:worker_threads\", // Missing exports: isInternalThread, isMarkedAsUntransferable, locks, markAsUncloneable, postMessageToThread, threadName\n  \"node:zlib\", // Missing exports: ZstdCompress, ZstdDecompress, createZstdCompress, createZstdDecompress, zstdCompress, zstdCompressSync, zstdDecompress, zstdDecompressSync\n];\n\n// prettier-ignore\nexport const unsupportedNodeModules = [\n  \"node:_http_client\",\n  \"node:_http_incoming\",\n  \"node:_stream_wrap\",\n  \"node:sea\",\n  \"node:test/reporters\",\n];\n"
  },
  {
    "path": "src/presets/deno/unenv/preset.ts",
    "content": "import type { Preset } from \"unenv\";\nimport * as denoCompat from \"./node-compat.ts\";\n\n// https://platform-node-compat.deno.dev/\n// https://platform-node-compat.netlify.app/\n\nexport const unenvDeno: Preset = {\n  meta: {\n    name: \"nitro:deno\",\n  },\n  external: denoCompat.builtnNodeModules.map((m) => `node:${m}`),\n  alias: {\n    ...Object.fromEntries(\n      denoCompat.builtnNodeModules.flatMap((m) => [\n        [m, m],\n        [m.replace(\"node:\", \"\"), m],\n      ])\n    ),\n  },\n  inject: {\n    global: \"unenv/polyfill/globalthis\",\n    process: \"node:process\",\n    clearImmediate: [\"node:timers\", \"clearImmediate\"],\n    setImmediate: [\"node:timers\", \"setImmediate\"],\n    Buffer: [\"node:buffer\", \"Buffer\"],\n  },\n};\n"
  },
  {
    "path": "src/presets/digitalocean/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst digitalOcean = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"digital-ocean\" as const,\n  }\n);\n\nexport default [digitalOcean] as const;\n"
  },
  {
    "path": "src/presets/firebase/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport { version as nitroVersion } from \"nitro/meta\";\nimport { join, relative } from \"pathe\";\nimport { stringifyYAML } from \"confbox\";\nimport type { AppHostingOutputBundleConfig } from \"./types.ts\";\n\nexport type { FirebaseOptions as PresetOptions } from \"./types.ts\";\n\nconst firebaseAppHosting = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n    hooks: {\n      async compiled(nitro) {\n        const serverEntry = join(nitro.options.output.serverDir, \"index.mjs\");\n        await writeFile(\n          join(nitro.options.rootDir, \".apphosting/bundle.yaml\"),\n          stringifyYAML({\n            version: \"v1\",\n            runConfig: {\n              runCommand: `node ${relative(nitro.options.rootDir, serverEntry)}`,\n              ...nitro.options.firebase?.appHosting,\n            },\n            metadata: {\n              framework: nitro.options.framework.name || \"nitro\",\n              frameworkVersion: nitro.options.framework.version || \"2.x\",\n              adapterPackageName: \"nitro\",\n              adapterVersion: nitroVersion,\n            },\n            outputFiles: {\n              serverApp: {\n                include: [relative(nitro.options.rootDir, nitro.options.output.dir)],\n              },\n            },\n          } satisfies AppHostingOutputBundleConfig),\n          true\n        );\n      },\n    },\n  },\n  {\n    name: \"firebase-app-hosting\" as const,\n    stdName: \"firebase_app_hosting\",\n  }\n);\n\nexport default [firebaseAppHosting] as const;\n"
  },
  {
    "path": "src/presets/firebase/types.ts",
    "content": "export interface FirebaseOptions {\n  appHosting: Partial<AppHostingOutputBundleConfig[\"runConfig\"]>;\n}\n\n// Source: https://github.com/FirebaseExtended/firebase-framework-tools/blob/main/packages/%40apphosting/common/src/index.ts\nexport interface AppHostingOutputBundleConfig {\n  version: \"v1\";\n\n  // Fields needed to configure the App Hosting server\n  runConfig: {\n    /** Command to start the server (e.g. \"node dist/index.js\"). Assume this command is run from the root dir of the workspace. */\n    runCommand: string;\n    /** Environment variables set when the app is run. */\n    environmentVariables?: Array<{\n      /** Name of the variable. */\n      variable: string;\n      /** Value associated with the variable. */\n      value: string;\n      /** Where the variable will be available, for now only RUNTIME is supported. */\n      availability: \"RUNTIME\"[];\n    }>;\n    // See https://firebase.google.com/docs/reference/apphosting/rest/v1beta/projects.locations.backends.builds#runconfig for documentation on the next fields\n    /** The maximum number of concurrent requests that each server instance can receive. */\n    concurrency?: number;\n    /** The number of CPUs used in a single server instance. */\n    cpu?: number;\n    /** The amount of memory available for a server instance. */\n    memoryMiB?: number;\n    /** The limit on the minimum number of function instances that may coexist at a given time. */\n    minInstances?: number;\n    /** The limit on the maximum number of function instances that may coexist at a given time. */\n    maxInstances?: number;\n  };\n\n  // Additional fields needed for identifying the framework and adapter being used\n  metadata: {\n    // Name of the adapter (this should be the official package name) e.g. \"@apphosting/adapter-nextjs\"\n    adapterPackageName: string;\n    // Version of the adapter, e.g. \"18.0.1\"\n    adapterVersion: string;\n    // Name of the framework that is being supported, e.g. \"angular\"\n    framework: string;\n    // Version of the framework that is being supported, e.g. \"18.0.1\"\n    frameworkVersion?: string;\n  };\n\n  // Optional outputFiles for frameworks to optimize server files + static assets.\n  outputFiles?: {\n    /** serverApp holds a list of directories + files relative to the app root dir that frameworks need to deploy to the App Hosting server. */\n    serverApp: {\n      include: string[];\n    };\n  };\n}\n"
  },
  {
    "path": "src/presets/flightcontrol/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst flightControl = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"flight-control\" as const,\n  }\n);\n\nexport default [flightControl] as const;\n"
  },
  {
    "path": "src/presets/genezio/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst genezio = defineNitroPreset(\n  {\n    extends: \"aws_lambda\",\n  },\n  {\n    name: \"genezio\" as const,\n  }\n);\nexport default [genezio] as const;\n"
  },
  {
    "path": "src/presets/heroku/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst heroku = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"heroku\" as const,\n  }\n);\n\nexport default [heroku] as const;\n"
  },
  {
    "path": "src/presets/iis/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { writeIISFiles, writeIISNodeFiles } from \"./utils.ts\";\n\nconst iisHandler = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n    hooks: {\n      async compiled(nitro: Nitro) {\n        await writeIISFiles(nitro);\n      },\n    },\n  },\n  {\n    name: \"iis-handler\" as const,\n  }\n);\n\nconst iisNode = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n    hooks: {\n      async compiled(nitro: Nitro) {\n        await writeIISNodeFiles(nitro);\n      },\n    },\n  },\n  {\n    name: \"iis-node\" as const,\n  }\n);\n\nexport default [iisHandler, iisNode] as const;\n"
  },
  {
    "path": "src/presets/iis/utils.ts",
    "content": "import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { defu } from \"defu\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { resolve } from \"pathe\";\n\nexport async function writeIISFiles(nitro: Nitro) {\n  await writeFile(resolve(nitro.options.output.dir, \"web.config\"), await iisXmlTemplate(nitro));\n}\n\nexport async function writeIISNodeFiles(nitro: Nitro) {\n  await writeFile(resolve(nitro.options.output.dir, \"web.config\"), await iisnodeXmlTemplate(nitro));\n\n  await writeFile(\n    resolve(nitro.options.output.dir, \"index.js\"),\n    /*js */ `\n    if (process.env.PORT.startsWith('\\\\\\\\')) {\n      process.env.NITRO_UNIX_SOCKET = process.env.PORT\n      delete process.env.PORT\n    }\n    import('./server/index.mjs');\n    `\n  );\n}\n\nasync function iisnodeXmlTemplate(nitro: Nitro) {\n  const path = resolve(nitro.options.rootDir, \"web.config\");\n  const originalString = /* xml */ `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n  <!--\n       This configuration file is required if iisnode is used to run node processes behind\n       IIS or IIS Express.  For more information, visit:\n       https://github.com/Azure/iisnode/blob/master/src/samples/configuration/web.config\n  -->\n  <configuration>\n    <system.webServer>\n      <!-- Visit http://blogs.msdn.com/b/windowsazure/archive/2013/11/14/introduction-to-websockets-on-windows-azure-web-sites.aspx for more information on WebSocket support -->\n      <webSocket enabled=\"false\" />\n      <handlers>\n        <!-- Indicates that the index.js file is a Node.js site to be handled by the iisnode module -->\n        <add name=\"iisnode\" path=\"index.js\" verb=\"*\" modules=\"iisnode\" />\n      </handlers>\n      <rewrite>\n        <rules>\n          <!-- Do not interfere with requests for node-inspector debugging -->\n          <rule name=\"NodeInspector\" patternSyntax=\"ECMAScript\" stopProcessing=\"true\">\n            <match url=\"^index.js/debug[/]?\" />\n          </rule>\n\n          <!-- First we consider whether the incoming URL matches a physical file in the /public folder -->\n          <rule name=\"StaticContent\">\n            <action type=\"Rewrite\" url=\"public{PATH_INFO}\" />\n          </rule>\n\n          <!-- All other URLs are mapped to the Node.js site entrypoint -->\n          <rule name=\"DynamicContent\">\n            <conditions>\n              <add input=\"{REQUEST_FILENAME}\" matchType=\"IsFile\" negate=\"True\" />\n            </conditions>\n            <action type=\"Rewrite\" url=\"index.js\" />\n          </rule>\n        </rules>\n      </rewrite>\n\n      <!-- 'bin' directory has no special meaning in Node.js and apps can be placed in it -->\n      <security>\n        <requestFiltering>\n          <hiddenSegments>\n            <remove segment=\"bin\" />\n          </hiddenSegments>\n          <requestLimits maxAllowedContentLength=\"4294967295\" />\n        </requestFiltering>\n      </security>\n\n      <!-- Make sure error responses are left untouched -->\n      <httpErrors existingResponse=\"PassThrough\" />\n\n      <!--\n        You can control how Node is hosted within IIS using the following options:\n          * watchedFiles: semi-colon separated list of files that will be watched for changes to restart the server\n          * node_env: will be propagated to node as NODE_ENV environment variable\n          * debuggingEnabled - controls whether the built-in debugger is enabled\n        See https://github.com/Azure/iisnode/blob/master/src/samples/configuration/web.config for a full list of options\n      -->\n      <iisnode\n        watchedFiles=\"index.js\"\n        node_env=\"production\"\n        debuggingEnabled=\"false\"\n        loggingEnabled=\"false\"\n      />\n    </system.webServer>\n  </configuration>\n`;\n  if (existsSync(path)) {\n    const fileString = await readFile(path, \"utf8\");\n    const originalWebConfig: Record<string, unknown> = await parseXmlDoc(originalString);\n    const fileWebConfig: Record<string, unknown> = await parseXmlDoc(fileString);\n\n    if (nitro.options.iis?.mergeConfig && !nitro.options.iis.overrideConfig) {\n      return buildNewXmlDoc(defu(fileWebConfig, originalWebConfig));\n    }\n    if (nitro.options.iis?.overrideConfig) {\n      return buildNewXmlDoc({ ...fileWebConfig });\n    }\n  }\n  return originalString;\n}\n\nasync function iisXmlTemplate(nitro: Nitro) {\n  const path = resolve(nitro.options.rootDir, \"web.config\");\n  const originalString = /* xml */ `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<configuration>\n  <system.webServer>\n    <handlers>\n      <add name=\"httpPlatformHandler\" path=\"*\" verb=\"*\" modules=\"httpPlatformHandler\" resourceType=\"Unspecified\" requireAccess=\"Script\" />\n    </handlers>\n    <httpPlatform stdoutLogEnabled=\"true\" stdoutLogFile=\".\\\\logs\\\\node.log\" startupTimeLimit=\"20\" processPath=\"C:\\\\Program Files\\\\nodejs\\\\node.exe\" arguments=\".\\\\server\\\\index.mjs\">\n      <environmentVariables>\n        <environmentVariable name=\"PORT\" value=\"%HTTP_PLATFORM_PORT%\" />\n        <environmentVariable name=\"NODE_ENV\" value=\"Production\" />\n      </environmentVariables>\n    </httpPlatform>\n  </system.webServer>\n</configuration>\n`;\n  if (existsSync(path)) {\n    const fileString = await readFile(path, \"utf8\");\n    const originalWebConfig: Record<string, unknown> = await parseXmlDoc(originalString);\n    const fileWebConfig: Record<string, unknown> = await parseXmlDoc(fileString);\n\n    if (nitro.options.iis?.mergeConfig && !nitro.options.iis.overrideConfig) {\n      return buildNewXmlDoc(defu(fileWebConfig, originalWebConfig));\n    }\n    if (nitro.options.iis?.overrideConfig) {\n      return buildNewXmlDoc({ ...fileWebConfig });\n    }\n  }\n  return originalString;\n}\n\n//  XML Helpers\nasync function parseXmlDoc(xml: string): Promise<Record<string, unknown>> {\n  const { Parser } = await import(\"xml2js\");\n\n  if (xml === undefined || !xml) {\n    return {};\n  }\n  const parser = new Parser({ explicitArray: false });\n  let parsedRecord: Record<string, unknown> = {};\n  parser.parseString(xml, (_, r) => {\n    parsedRecord = r;\n  });\n  return parsedRecord;\n}\n\nasync function buildNewXmlDoc(xmlObj: Record<string, unknown>): Promise<string> {\n  const { Builder } = await import(\"xml2js\");\n  const builder = new Builder();\n  return builder.buildObject({ ...xmlObj });\n}\n"
  },
  {
    "path": "src/presets/index.ts",
    "content": "export { resolvePreset } from \"./_resolve.ts\";\n\nexport type { PresetOptions, PresetName, PresetNameInput } from \"./_types.gen.ts\";\n"
  },
  {
    "path": "src/presets/koyeb/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst koyeb = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"koyeb\" as const,\n  }\n);\n\nexport default [koyeb] as const;\n"
  },
  {
    "path": "src/presets/netlify/preset.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { defineNitroPreset } from \"../_utils/preset.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport type { Config, Manifest } from \"@netlify/edge-functions\";\nimport { dirname, join } from \"pathe\";\nimport { unenvDeno } from \"../deno/unenv/preset.ts\";\nimport {\n  generateNetlifyFunction,\n  getGeneratorString,\n  getStaticPaths,\n  writeHeaders,\n  writeRedirects,\n} from \"./utils.ts\";\n\nexport type { NetlifyOptions as PresetOptions } from \"./types.ts\";\n\n// Netlify functions\nconst netlify = defineNitroPreset(\n  {\n    entry: \"./netlify/runtime/netlify\",\n    manifest: {\n      deploymentId: process.env.DEPLOY_ID,\n    },\n    output: {\n      dir: \"{{ rootDir }}/.netlify/functions-internal\",\n      publicDir: \"{{ rootDir }}/dist/{{ baseURL }}\",\n    },\n    prerender: {\n      // Prevents an unnecessary redirect from /page/ to /page when accessing prerendered content.\n      // Reference: https://answers.netlify.com/t/support-guide-how-can-i-alter-trailing-slash-behaviour-in-my-urls-will-enabling-pretty-urls-help/31191\n      // Reference: https://nitro.build/config#prerender\n      autoSubfolderIndex: false,\n    },\n    rollupConfig: {\n      output: {\n        entryFileNames: \"main.mjs\",\n      },\n    },\n    hooks: {\n      async compiled(nitro: Nitro) {\n        await writeHeaders(nitro);\n        await writeRedirects(nitro);\n\n        await fsp.writeFile(\n          join(nitro.options.output.dir, \"server\", \"server.mjs\"),\n          generateNetlifyFunction(nitro)\n        );\n\n        if (nitro.options.netlify?.images) {\n          nitro.options.netlify.config ||= {};\n          nitro.options.netlify.config.images ||= nitro.options.netlify?.images;\n        }\n\n        if (Object.keys(nitro.options.netlify?.config || {}).length > 0) {\n          const configPath = join(nitro.options.output.dir, \"../deploy/v1/config.json\");\n          await fsp.mkdir(dirname(configPath), { recursive: true });\n          await fsp.writeFile(configPath, JSON.stringify(nitro.options.netlify?.config), \"utf8\");\n        }\n      },\n    },\n  },\n  {\n    name: \"netlify\" as const,\n    stdName: \"netlify\",\n  }\n);\n\n// Netlify edge\nconst netlifyEdge = defineNitroPreset(\n  {\n    extends: \"base-worker\",\n    entry: \"./netlify/runtime/netlify-edge\",\n    manifest: {\n      deploymentId: process.env.DEPLOY_ID,\n    },\n    exportConditions: [\"netlify\"],\n    output: {\n      serverDir: \"{{ rootDir }}/.netlify/edge-functions/server\",\n      publicDir: \"{{ rootDir }}/dist/{{ baseURL }}\",\n    },\n    prerender: {\n      // Prevents an unnecessary redirect from /page/ to /page when accessing prerendered content.\n      // Reference: https://answers.netlify.com/t/support-guide-how-can-i-alter-trailing-slash-behaviour-in-my-urls-will-enabling-pretty-urls-help/31191\n      // Reference: https://nitro.build/config#prerender\n      autoSubfolderIndex: false,\n    },\n    rollupConfig: {\n      output: {\n        entryFileNames: \"server.js\",\n        format: \"esm\",\n      },\n    },\n    unenv: unenvDeno,\n    hooks: {\n      async compiled(nitro: Nitro) {\n        await writeHeaders(nitro);\n        await writeRedirects(nitro);\n\n        // https://docs.netlify.com/edge-functions/create-integration/\n        const manifest: Manifest = {\n          version: 1,\n          functions: [\n            {\n              path: \"/*\",\n              excludedPath: getStaticPaths(\n                nitro.options.publicAssets,\n                nitro.options.baseURL\n              ) as Config[\"excludedPath\"],\n              name: \"edge server handler\",\n              function: \"server\",\n              generator: getGeneratorString(nitro),\n            },\n          ],\n        };\n        const manifestPath = join(nitro.options.rootDir, \".netlify/edge-functions/manifest.json\");\n        await fsp.mkdir(dirname(manifestPath), { recursive: true });\n        await fsp.writeFile(manifestPath, JSON.stringify(manifest, null, 2));\n      },\n    },\n  },\n  {\n    name: \"netlify-edge\" as const,\n  }\n);\n\nconst netlifyStatic = defineNitroPreset(\n  {\n    extends: \"static\",\n    manifest: {\n      deploymentId: process.env.DEPLOY_ID,\n    },\n    output: {\n      dir: \"{{ rootDir }}/dist\",\n      publicDir: \"{{ rootDir }}/dist/{{ baseURL }}\",\n    },\n    prerender: {\n      // Prevents an unnecessary redirect from /page/ to /page when accessing prerendered content.\n      // Reference: https://answers.netlify.com/t/support-guide-how-can-i-alter-trailing-slash-behaviour-in-my-urls-will-enabling-pretty-urls-help/31191\n      // Reference: https://nitro.build/config#prerender\n      autoSubfolderIndex: false,\n    },\n    commands: {\n      preview: \"npx serve ./\",\n    },\n    hooks: {\n      async compiled(nitro: Nitro) {\n        await writeHeaders(nitro);\n        await writeRedirects(nitro);\n      },\n    },\n  },\n  {\n    name: \"netlify-static\" as const,\n    stdName: \"netlify\",\n    static: true,\n  }\n);\n\nexport default [netlify, netlifyEdge, netlifyStatic] as const;\n"
  },
  {
    "path": "src/presets/netlify/runtime/netlify-edge.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport { isPublicAssetURL } from \"#nitro/virtual/public-assets\";\nimport type { Context } from \"@netlify/edge-functions\";\nimport type { ServerRequest } from \"srvx\";\n\nconst nitroApp = useNitroApp();\n\n// https://docs.netlify.com/edge-functions/api/\nexport default async function netlifyEdge(netlifyReq: Request, context: Context) {\n  // srvx compatibility\n  const req = netlifyReq as unknown as ServerRequest;\n  req.ip = context.ip;\n  req.runtime ??= { name: \"netlify-edge\" };\n  req.runtime.netlify ??= { context } as any;\n\n  const url = new URL(req.url);\n\n  if (isPublicAssetURL(url.pathname)) {\n    return;\n  }\n\n  if (!req.headers.has(\"x-forwarded-proto\") && url.protocol === \"https:\") {\n    req.headers.set(\"x-forwarded-proto\", \"https\");\n  }\n\n  return nitroApp.fetch(req);\n}\n"
  },
  {
    "path": "src/presets/netlify/runtime/netlify.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport type { ServerRequest } from \"srvx\";\n\nconst nitroApp = useNitroApp();\n\nconst ONE_YEAR_IN_SECONDS = 365 * 24 * 60 * 60;\n\nconst handler = async (req: ServerRequest): Promise<Response> => {\n  req.runtime ??= { name: \"netlify\" };\n  req.ip ??= req.headers.get(\"x-nf-client-connection-ip\") || undefined;\n\n  const response = await nitroApp.fetch(req);\n\n  const isr = (req.context?.routeRules || {})?.isr?.options;\n  if (isr) {\n    const maxAge = typeof isr === \"number\" ? isr : ONE_YEAR_IN_SECONDS;\n    const revalidateDirective =\n      typeof isr === \"number\" ? `stale-while-revalidate=${ONE_YEAR_IN_SECONDS}` : \"must-revalidate\";\n    if (!response.headers.has(\"Cache-Control\")) {\n      response.headers.set(\"Cache-Control\", \"public, max-age=0, must-revalidate\");\n    }\n    response.headers.set(\n      \"Netlify-CDN-Cache-Control\",\n      `public, max-age=${maxAge}, ${revalidateDirective}, durable`\n    );\n  }\n\n  return response;\n};\n\nexport default handler;\n"
  },
  {
    "path": "src/presets/netlify/types.ts",
    "content": "// https://docs.netlify.com/build/frameworks/frameworks-api/\n\nexport interface NetlifyOptions {\n  /** @deprecated Use `config.images` */\n  images?: NetlifyImagesConfig;\n  config?: NetlifyConfigJson;\n  // skewProtection?: NetlifySkewProtectionJson;\n  // edgeFunctionsImportMap?: NetlifyImportMapJson;\n  // blobsMetadata?: Record<string, NetlifyBlobMetadata>;\n}\n\nexport interface NetlifyConfigJson {\n  edge_functions?: NetlifyEdgeFunctionDeclaration[];\n  functions?: NetlifyFunctionsConfig | NetlifyFunctionsConfigByPattern;\n  headers?: NetlifyHeaderRule[];\n  images?: NetlifyImagesConfig;\n  redirects?: NetlifyRedirectRule[];\n  \"redirects!\"?: NetlifyRedirectRule[];\n}\n\ninterface NetlifyEdgeFunctionDeclaration {\n  function: string;\n  path?: string;\n  pattern?: string;\n  excludedPath?: string;\n  excludedPattern?: string;\n  cache?: string;\n  [key: string]: unknown;\n}\n\ninterface NetlifyFunctionsConfig extends NetlifyFunctionInlineConfig {\n  directory?: string;\n}\n\nexport type NetlifyFunctionsConfigByPattern = Record<string, NetlifyFunctionInlineConfig>;\n\ninterface NetlifyFunctionInlineConfig {\n  included_files?: string[];\n  [key: string]: unknown;\n}\n\ninterface NetlifyHeaderRule {\n  for: string;\n  values: Record<string, string>;\n  [key: string]: unknown;\n}\n\ninterface NetlifyImagesConfig {\n  remote_images?: string[];\n  [key: string]: unknown;\n}\n\ninterface NetlifyRedirectRule {\n  from: string;\n  to: string;\n  status?: number;\n  force?: boolean;\n  conditions?: Record<string, string[]>;\n  query?: Record<string, string>;\n  [key: string]: unknown;\n}\n\nexport interface NetlifySkewProtectionJson {\n  patterns: string[];\n  sources: NetlifySkewProtectionSource[];\n  [key: string]: unknown;\n}\n\ninterface NetlifySkewProtectionSource {\n  type: \"cookie\" | \"header\" | \"query\";\n  name: string;\n  [key: string]: unknown;\n}\n\nexport interface NetlifyImportMapJson {\n  imports?: Record<string, string>;\n  scopes?: Record<string, Record<string, string>>;\n  [key: string]: unknown;\n}\n\nexport interface NetlifyBlobMetadata {\n  headers?: Record<string, string>;\n  [key: string]: unknown;\n}\n"
  },
  {
    "path": "src/presets/netlify/utils.ts",
    "content": "import { existsSync, promises as fsp } from \"node:fs\";\nimport type { Nitro, PublicAssetDir } from \"nitro/types\";\nimport { join } from \"pathe\";\nimport { joinURL } from \"ufo\";\n\nexport async function writeRedirects(nitro: Nitro) {\n  const redirectsPath = join(nitro.options.output.publicDir, \"_redirects\");\n\n  let contents = \"\";\n  if (nitro.options.static) {\n    const staticFallback = existsSync(join(nitro.options.output.publicDir, \"404.html\"))\n      ? \"/* /404.html 404\"\n      : \"\";\n    contents += staticFallback;\n  }\n\n  const rules = Object.entries(nitro.options.routeRules).sort(\n    (a, b) => a[0].split(/\\/(?!\\*)/).length - b[0].split(/\\/(?!\\*)/).length\n  );\n\n  for (const [key, routeRules] of rules.filter(([_, routeRules]) => routeRules.redirect)) {\n    let code = routeRules.redirect!.status;\n    // TODO: Remove map when netlify support 307/308\n    if (code === 307) {\n      code = 302;\n    }\n    if (code === 308) {\n      code = 301;\n    }\n    contents =\n      `${key.replace(\"/**\", \"/*\")}\\t${routeRules.redirect!.to.replace(\n        \"/**\",\n        \"/:splat\"\n      )}\\t${code}\\n` + contents;\n  }\n\n  if (existsSync(redirectsPath)) {\n    const currentRedirects = await fsp.readFile(redirectsPath, \"utf8\");\n    if (/^\\/\\* /m.test(currentRedirects)) {\n      nitro.logger.info(\n        \"Not adding Nitro fallback to `_redirects` (as an existing fallback was found).\"\n      );\n      return;\n    }\n    nitro.logger.info(\"Adding Nitro fallback to `_redirects` to handle all unmatched routes.\");\n    contents = currentRedirects + \"\\n\" + contents;\n  }\n\n  await fsp.writeFile(redirectsPath, contents);\n}\n\nexport async function writeHeaders(nitro: Nitro) {\n  const headersPath = join(nitro.options.output.publicDir, \"_headers\");\n  let contents = \"\";\n\n  const rules = Object.entries(nitro.options.routeRules).sort(\n    (a, b) => b[0].split(/\\/(?!\\*)/).length - a[0].split(/\\/(?!\\*)/).length\n  );\n\n  for (const [path, routeRules] of rules.filter(([_, routeRules]) => routeRules.headers)) {\n    const headers = [\n      path.replace(\"/**\", \"/*\"),\n      ...Object.entries({ ...routeRules.headers }).map(\n        ([header, value]) => `  ${header}: ${value}`\n      ),\n    ].join(\"\\n\");\n\n    contents += headers + \"\\n\";\n  }\n\n  if (existsSync(headersPath)) {\n    const currentHeaders = await fsp.readFile(headersPath, \"utf8\");\n    if (/^\\/\\* /m.test(currentHeaders)) {\n      nitro.logger.info(\n        \"Not adding Nitro fallback to `_headers` (as an existing fallback was found).\"\n      );\n      return;\n    }\n    nitro.logger.info(\"Adding Nitro fallback to `_headers` to handle all unmatched routes.\");\n    contents = currentHeaders + \"\\n\" + contents;\n  }\n\n  await fsp.writeFile(headersPath, contents);\n}\n\nexport function getStaticPaths(publicAssets: PublicAssetDir[], baseURL: string): string[] {\n  return [\n    \"/.netlify/*\", // TODO: should this be also be prefixed with baseURL?\n    ...publicAssets\n      .filter((a) => a.fallthrough !== true && a.baseURL && a.baseURL !== \"/\")\n      .map((a) => joinURL(baseURL, a.baseURL!, \"*\")),\n  ];\n}\n\n// This is written to the functions directory. It just re-exports the compiled handler,\n// along with its config. We do this instead of compiling the entrypoint directly because\n// the Netlify platform actually statically analyzes the function file to read the config;\n// if we compiled the entrypoint directly, it would be chunked and wouldn't be analyzable.\nexport function generateNetlifyFunction(nitro: Nitro) {\n  return /* js */ `\nexport { default } from \"./main.mjs\";\nexport const config = {\n  name: \"server handler\",\n  generator: \"${getGeneratorString(nitro)}\",\n  path: \"/*\",\n  nodeBundler: \"none\",\n  includedFiles: [\"**\"],\n  excludedPath: ${JSON.stringify(getStaticPaths(nitro.options.publicAssets, nitro.options.baseURL))},\n  preferStatic: true,\n};\n    `.trim();\n}\n\nexport function getGeneratorString(nitro: Nitro) {\n  return `${nitro.options.framework.name}@${nitro.options.framework.version}`;\n}\n"
  },
  {
    "path": "src/presets/node/cluster.ts",
    "content": "import { resolve } from \"pathe\";\nimport { writeFile } from \"../../utils/fs.ts\";\nimport { defineNitroPreset } from \"../_utils/preset.ts\";\n\nexport const nodeCluster = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n    entry: \"./node/runtime/node-cluster\",\n    rollupConfig: {\n      output: {\n        entryFileNames: \"worker.mjs\",\n      },\n    },\n    hooks: {\n      async compiled(nitro) {\n        await writeFile(resolve(nitro.options.output.serverDir, \"index.mjs\"), nodeClusterEntry());\n      },\n    },\n  },\n  {\n    name: \"node-cluster\" as const,\n  }\n);\n\nfunction nodeClusterEntry() {\n  return /* js */ `\nimport cluster from \"node:cluster\";\nimport os from \"node:os\";\n\nif (cluster.isPrimary) {\n  const numberOfWorkers =\n    Number.parseInt(process.env.NITRO_CLUSTER_WORKERS || \"\") ||\n    (os.cpus().length > 0 ? os.cpus().length : 1);\n  for (let i = 0; i < numberOfWorkers; i++) {\n    cluster.fork({\n      WORKER_ID: i + 1,\n    });\n  }\n} else {\n import(\"./worker.mjs\").catch((error) => {\n    console.error(error);\n    process.exit(1);\n  });\n}\n`;\n}\n"
  },
  {
    "path": "src/presets/node/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport { nodeCluster } from \"./cluster.ts\";\n\nconst nodeServer = defineNitroPreset(\n  {\n    entry: \"./node/runtime/node-server\",\n    serveStatic: true,\n    commands: {\n      preview: \"node ./server/index.mjs\",\n    },\n  },\n  {\n    name: \"node-server\" as const,\n    aliases: [\"node\"],\n  }\n);\n\nconst nodeMiddleware = defineNitroPreset(\n  {\n    entry: \"./node/runtime/node-middleware\",\n  },\n  {\n    name: \"node-middleware\" as const,\n  }\n);\n\nexport default [nodeServer, nodeCluster, nodeMiddleware] as const;\n"
  },
  {
    "path": "src/presets/node/runtime/node-cluster.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport cluster from \"node:cluster\";\nimport { NodeRequest, serve } from \"srvx/node\";\nimport wsAdapter from \"crossws/adapters/node\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\nimport { trapUnhandledErrors } from \"#nitro/runtime/error/hooks\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst _parsedPort = Number.parseInt(process.env.NITRO_PORT ?? process.env.PORT ?? \"\");\nconst port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort;\n\nconst host = process.env.NITRO_HOST || process.env.HOST;\nconst cert = process.env.NITRO_SSL_CERT;\nconst key = process.env.NITRO_SSL_KEY;\n// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO\n\nconst clusterId = cluster.isWorker && process.env.WORKER_ID;\nif (clusterId) {\n  console.log(`Worker #${clusterId} started`);\n}\n\nconst nitroApp = useNitroApp();\n\nconst server = serve({\n  port,\n  hostname: host,\n  tls: cert && key ? { cert, key } : undefined,\n  node: { exclusive: false },\n  silent: clusterId ? clusterId !== \"1\" : undefined,\n  fetch: nitroApp.fetch,\n});\n\nif (import.meta._websocket) {\n  const { handleUpgrade } = wsAdapter({ resolve: resolveWebsocketHooks });\n  server.node!.server!.on(\"upgrade\", (req, socket, head) => {\n    handleUpgrade(\n      req,\n      socket,\n      head,\n      // @ts-expect-error (upgrade is not typed)\n      new NodeRequest({ req, upgrade: { socket, head } })\n    );\n  });\n}\n\ntrapUnhandledErrors();\n\n// Scheduled tasks\nif (import.meta._tasks) {\n  startScheduleRunner({ waitUntil: server.waitUntil });\n}\n\nexport default {};\n"
  },
  {
    "path": "src/presets/node/runtime/node-middleware.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { toNodeHandler } from \"srvx/node\";\nimport wsAdapter from \"crossws/adapters/node\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst nitroApp = useNitroApp();\n\nexport const middleware = toNodeHandler(nitroApp.fetch);\n\nconst ws = import.meta._websocket ? wsAdapter({ resolve: resolveWebsocketHooks }) : undefined;\n\nexport const handleUpgrade = ws?.handleUpgrade;\n\n// Scheduled tasks\nif (import.meta._tasks) {\n  startScheduleRunner();\n}\n"
  },
  {
    "path": "src/presets/node/runtime/node-server.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { NodeRequest, serve } from \"srvx/node\";\nimport wsAdapter from \"crossws/adapters/node\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\nimport { trapUnhandledErrors } from \"#nitro/runtime/error/hooks\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\n\nconst _parsedPort = Number.parseInt(process.env.NITRO_PORT ?? process.env.PORT ?? \"\");\nconst port = Number.isNaN(_parsedPort) ? 3000 : _parsedPort;\n\nconst host = process.env.NITRO_HOST || process.env.HOST;\nconst cert = process.env.NITRO_SSL_CERT;\nconst key = process.env.NITRO_SSL_KEY;\n// const socketPath = process.env.NITRO_UNIX_SOCKET; // TODO\n\nconst nitroApp = useNitroApp();\n\nconst server = serve({\n  port,\n  hostname: host,\n  tls: cert && key ? { cert, key } : undefined,\n  fetch: nitroApp.fetch,\n});\n\nif (import.meta._websocket) {\n  const { handleUpgrade } = wsAdapter({ resolve: resolveWebsocketHooks });\n  server.node!.server!.on(\"upgrade\", (req, socket, head) => {\n    handleUpgrade(\n      req,\n      socket,\n      head,\n      // @ts-expect-error (upgrade is not typed)\n      new NodeRequest({ req, upgrade: { socket, head } })\n    );\n  });\n}\n\ntrapUnhandledErrors();\n\n// Scheduled tasks\nif (import.meta._tasks) {\n  startScheduleRunner({ waitUntil: server.waitUntil });\n}\n\nexport default {};\n"
  },
  {
    "path": "src/presets/platform.sh/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst platformSh = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"platform-sh\" as const,\n  }\n);\n\nexport default [platformSh] as const;\n"
  },
  {
    "path": "src/presets/render.com/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst renderCom = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"render-com\" as const,\n  }\n);\n\nexport default [renderCom] as const;\n"
  },
  {
    "path": "src/presets/standard/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst standard = defineNitroPreset(\n  {\n    entry: \"./standard/runtime/server\",\n    serveStatic: false,\n    output: {\n      publicDir: \"{{ output.dir }}/public/{{ baseURL }}\",\n    },\n    commands: {\n      preview: \"npx srvx --prod ./\",\n    },\n    alias: {\n      srvx: \"srvx/generic\",\n      \"srvx/bun\": \"srvx/bun\",\n      \"srvx/deno\": \"srvx/deno\",\n      \"srvx/node\": \"srvx/node\",\n      \"srvx/generic\": \"srvx/generic\",\n    },\n  },\n  {\n    name: \"standard\" as const,\n  }\n);\n\nexport default [standard] as const;\n"
  },
  {
    "path": "src/presets/standard/runtime/server.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\n\nconst nitroApp = useNitroApp();\n\nexport default {\n  fetch: nitroApp.fetch,\n};\n"
  },
  {
    "path": "src/presets/stormkit/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst stormkit = defineNitroPreset(\n  {\n    entry: \"./stormkit/runtime/stormkit\",\n    output: {\n      dir: \"{{ rootDir }}/.stormkit\",\n      publicDir: \"{{ rootDir }}/.stormkit/public/{{ baseURL }}\",\n    },\n  },\n  {\n    name: \"stormkit\" as const,\n    stdName: \"stormkit\",\n  }\n);\n\nexport default [stormkit] as const;\n"
  },
  {
    "path": "src/presets/stormkit/runtime/stormkit.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport { awsResponseBody } from \"../../aws-lambda/runtime/_utils.ts\";\n\nimport type { Handler } from \"aws-lambda\";\nimport type { ServerRequest } from \"srvx\";\n\ntype StormkitEvent = {\n  url: string; // e.g. /my/path, /my/path?with=query\n  path: string;\n  method: string;\n  body?: string;\n  query?: Record<string, Array<string>>;\n  headers?: Record<string, string>;\n  rawHeaders?: Array<string>;\n};\n\ntype StormkitResponse = {\n  headers?: Record<string, string>;\n  body?: string;\n  buffer?: string;\n  statusCode: number;\n  errorMessage?: string;\n  errorStack?: string;\n};\n\nconst nitroApp = useNitroApp();\n\nexport const handler: Handler<StormkitEvent, StormkitResponse> = async function (event, context) {\n  const req = new Request(event.url, {\n    method: event.method || \"GET\",\n    headers: event.headers,\n    body: event.body,\n  }) as ServerRequest;\n\n  // srvx compatibility\n  req.runtime ??= { name: \"stormkit\" };\n  req.runtime.stormkit ??= { event, context } as any;\n\n  const response = await nitroApp.fetch(req);\n\n  const { body, isBase64Encoded } = await awsResponseBody(response);\n\n  return {\n    statusCode: response.status,\n    headers: normalizeOutgoingHeaders(response.headers),\n    [isBase64Encoded ? \"buffer\" : \"body\"]: body,\n  } satisfies StormkitResponse;\n};\n\nfunction normalizeOutgoingHeaders(headers: Headers): Record<string, string> {\n  return Object.fromEntries(\n    Object.entries(headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(\",\") : String(v)])\n  );\n}\n"
  },
  {
    "path": "src/presets/vercel/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { presetsDir } from \"nitro/meta\";\nimport { join } from \"pathe\";\nimport {\n  deprecateSWR,\n  generateFunctionFiles,\n  generateStaticFiles,\n  resolveVercelRuntime,\n} from \"./utils.ts\";\n\nexport type { VercelOptions as PresetOptions } from \"./types.ts\";\n\n// https://vercel.com/docs/build-output-api/v3\n\nconst vercel = defineNitroPreset(\n  {\n    entry: \"./vercel/runtime/vercel.{format}\",\n    manifest: {\n      deploymentId: process.env.VERCEL_DEPLOYMENT_ID,\n    },\n    vercel: {\n      skewProtection: !!process.env.VERCEL_SKEW_PROTECTION_ENABLED,\n      cronHandlerRoute: \"/_vercel/cron\",\n    },\n    output: {\n      dir: \"{{ rootDir }}/.vercel/output\",\n      serverDir: \"{{ output.dir }}/functions/__server.func\",\n      publicDir: \"{{ output.dir }}/static/{{ baseURL }}\",\n    },\n    commands: {\n      preview: \"npx srvx --static ../../static ./functions/__server.func/index.mjs\",\n      deploy: \"npx vercel deploy --prebuilt\",\n    },\n    hooks: {\n      \"build:before\": async (nitro: Nitro) => {\n        const logger = nitro.logger.withTag(\"vercel\");\n\n        // Runtime\n        const runtime = await resolveVercelRuntime(nitro);\n        if (runtime.startsWith(\"bun\") && !nitro.options.exportConditions!.includes(\"bun\")) {\n          nitro.options.exportConditions!.push(\"bun\");\n        }\n        logger.info(`Using \\`${runtime}\\` runtime.`);\n\n        // Entry handler format\n        let serverFormat = nitro.options.vercel?.entryFormat;\n        if (!serverFormat) {\n          const hasNodeHandler = nitro.routing.routes.routes\n            .flatMap((r) => r.data)\n            .some((h) => h.format === \"node\");\n          serverFormat = hasNodeHandler ? \"node\" : \"web\";\n        }\n        logger.info(`Using \\`${serverFormat}\\` entry format.`);\n        nitro.options.entry = nitro.options.entry.replace(\"{format}\", serverFormat);\n\n        // Cron tasks handler\n        if (\n          nitro.options.experimental.tasks &&\n          Object.keys(nitro.options.scheduledTasks || {}).length > 0\n        ) {\n          nitro.options.handlers.push({\n            route: nitro.options.vercel!.cronHandlerRoute || \"/_vercel/cron\",\n            lazy: true,\n            handler: join(presetsDir, \"vercel/runtime/cron-handler\"),\n          });\n        }\n      },\n      \"rollup:before\": (nitro: Nitro) => {\n        deprecateSWR(nitro);\n      },\n      async compiled(nitro: Nitro) {\n        await generateFunctionFiles(nitro);\n      },\n    },\n  },\n  {\n    name: \"vercel\" as const,\n    stdName: \"vercel\",\n  }\n);\n\nconst vercelStatic = defineNitroPreset(\n  {\n    extends: \"static\",\n    manifest: {\n      deploymentId: process.env.VERCEL_DEPLOYMENT_ID,\n    },\n    vercel: {\n      skewProtection: !!process.env.VERCEL_SKEW_PROTECTION_ENABLED,\n    },\n    output: {\n      dir: \"{{ rootDir }}/.vercel/output\",\n      publicDir: \"{{ output.dir }}/static/{{ baseURL }}\",\n    },\n    commands: {\n      preview: \"npx serve ./static\",\n    },\n    hooks: {\n      \"rollup:before\": (nitro: Nitro) => {\n        deprecateSWR(nitro);\n      },\n      async compiled(nitro: Nitro) {\n        await generateStaticFiles(nitro);\n      },\n    },\n  },\n  {\n    name: \"vercel-static\" as const,\n    stdName: \"vercel\",\n    static: true,\n  }\n);\n\nexport default [vercel, vercelStatic] as const;\n"
  },
  {
    "path": "src/presets/vercel/runtime/cron-handler.ts",
    "content": "import { timingSafeEqual } from \"node:crypto\";\nimport { defineHandler, HTTPError } from \"nitro/h3\";\nimport { runCronTasks } from \"#nitro/runtime/task\";\n\nexport default defineHandler(async (event) => {\n  // Validate CRON_SECRET if set - https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs\n  const cronSecret = process.env.CRON_SECRET;\n  if (cronSecret) {\n    const authHeader = event.req.headers.get(\"authorization\") || \"\";\n    const expected = `Bearer ${cronSecret}`;\n    const a = Buffer.from(authHeader);\n    const b = Buffer.from(expected);\n    if (a.length !== b.length || !timingSafeEqual(a, b)) {\n      throw new HTTPError(\"Unauthorized\", { status: 401 });\n    }\n  }\n\n  const cron = event.req.headers.get(\"x-vercel-cron-schedule\");\n  if (!cron) {\n    throw new HTTPError(\"Missing x-vercel-cron-schedule header\", { status: 400 });\n  }\n\n  await runCronTasks(cron, {\n    context: { waitUntil: event.req.waitUntil },\n    payload: {\n      scheduledTime: Date.now(),\n    },\n  });\n\n  return { success: true };\n});\n"
  },
  {
    "path": "src/presets/vercel/runtime/isr.ts",
    "content": "export const ISR_URL_PARAM = \"__isr_route\";\n\nexport function isrRouteRewrite(\n  reqUrl: string,\n  xNowRouteMatches: string | null\n): [pathname: string, search: string] | undefined {\n  if (xNowRouteMatches) {\n    const isrURL = new URLSearchParams(xNowRouteMatches).get(ISR_URL_PARAM);\n    if (isrURL) {\n      return [decodeURIComponent(isrURL), \"\"];\n    }\n  } else {\n    const queryIndex = reqUrl.indexOf(\"?\");\n    if (queryIndex !== -1) {\n      const params = new URLSearchParams(reqUrl.slice(queryIndex + 1));\n      const isrURL = params.get(ISR_URL_PARAM);\n      if (isrURL) {\n        params.delete(ISR_URL_PARAM);\n        return [decodeURIComponent(isrURL), params.toString()];\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/presets/vercel/runtime/vercel.node.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport type { NodeServerRequest, NodeServerResponse } from \"srvx\";\nimport { toNodeHandler } from \"srvx/node\";\nimport { useNitroApp, getRouteRules } from \"nitro/app\";\nimport { isrRouteRewrite } from \"./isr.ts\";\n\nconst nitroApp = useNitroApp();\n\nconst handler = toNodeHandler(nitroApp.fetch);\n\nexport default function nodeHandler(req: NodeServerRequest, res: NodeServerResponse) {\n  // https://vercel.com/docs/headers/request-headers#x-forwarded-for\n  // srvx node adapter uses req.socket.remoteAddress for req.ip\n  let ip: string | undefined;\n  Object.defineProperty(req.socket, \"remoteAddress\", {\n    get() {\n      const h = req.headers[\"x-forwarded-for\"] as string;\n      return (ip ??= h?.split?.(\",\").shift()?.trim());\n    },\n  });\n\n  // ISR route rewrite\n  const isrURL = isrRouteRewrite(req.url!, req.headers[\"x-now-route-matches\"] as string);\n  if (isrURL) {\n    const { routeRules } = getRouteRules(\"\", isrURL[0]);\n    if (routeRules?.isr) {\n      req.url = isrURL[0] + (isrURL[1] ? `?${isrURL[1]}` : \"\");\n    }\n  }\n\n  return handler(req as any, res as any);\n}\n"
  },
  {
    "path": "src/presets/vercel/runtime/vercel.web.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { useNitroApp, getRouteRules } from \"nitro/app\";\n\nimport type { ServerRequest } from \"srvx\";\nimport { isrRouteRewrite } from \"./isr.ts\";\n\nconst nitroApp = useNitroApp();\n\nexport default {\n  fetch(req: ServerRequest, context: { waitUntil: (promise: Promise<any>) => void }) {\n    // ISR route rewrite\n    const isrURL = isrRouteRewrite(req.url, req.headers.get(\"x-now-route-matches\"));\n    if (isrURL) {\n      const { routeRules } = getRouteRules(\"\", isrURL[0]);\n      if (routeRules?.isr) {\n        req = new Request(\n          new URL(isrURL[0] + (isrURL[1] ? `?${isrURL[1]}` : \"\"), req.url).href,\n          req\n        );\n      }\n    }\n\n    req.runtime ??= { name: \"vercel\" };\n    req.runtime.vercel = { context };\n\n    let ip: string | undefined;\n    Object.defineProperty(req, \"ip\", {\n      get() {\n        const h = req.headers.get(\"x-forwarded-for\");\n        return (ip ??= h?.split(\",\").shift()?.trim());\n      },\n    });\n\n    req.waitUntil = context?.waitUntil;\n\n    return nitroApp.fetch(req);\n  },\n};\n"
  },
  {
    "path": "src/presets/vercel/types.ts",
    "content": "/**\n * Vercel Build Output Configuration\n * @see https://vercel.com/docs/build-output-api/v3\n */\nexport interface VercelBuildConfigV3 {\n  version: 3;\n  routes?: (\n    | {\n        src: string;\n        dest?: string;\n        headers?: Record<string, string>;\n        continue?: boolean;\n        status?: number;\n      }\n    | {\n        handle: string;\n      }\n  )[];\n  images?: {\n    sizes: number[];\n    domains: string[];\n    remotePatterns?: {\n      protocol?: \"http\" | \"https\";\n      hostname: string;\n      port?: string;\n      pathname?: string;\n    }[];\n    minimumCacheTTL?: number;\n    formats?: (\"image/avif\" | \"image/webp\")[];\n    dangerouslyAllowSVG?: boolean;\n    contentSecurityPolicy?: string;\n  };\n  wildcard?: Array<{\n    domain: string;\n    value: string;\n  }>;\n  overrides?: Record<\n    string,\n    {\n      path?: string;\n      contentType?: string;\n    }\n  >;\n  cache?: string[];\n  bypassToken?: string;\n  framework?: {\n    version: string;\n  };\n  crons?: {\n    path: string;\n    schedule: string;\n  }[];\n}\n\n/**\n * https://vercel.com/docs/build-output-api/primitives#serverless-function-configuration\n * https://vercel.com/docs/build-output-api/primitives#node.js-config\n */\nexport interface VercelServerlessFunctionConfig {\n  /**\n   * Amount of memory (RAM in MB) that will be allocated to the Serverless Function.\n   */\n  memory?: number;\n\n  /**\n   * Specifies the instruction set \"architecture\" the Vercel Function supports.\n   *\n   * Either `x86_64` or `arm64`. The default value is `x86_64`\n   */\n  architecture?: \"x86_64\" | \"arm64\";\n\n  /**\n   * Maximum execution duration (in seconds) that will be allowed for the Serverless Function.\n   */\n  maxDuration?: number;\n\n  /**\n   * Map of additional environment variables that will be available to the Vercel Function,\n   * in addition to the env vars specified in the Project Settings.\n   */\n  environment?: Record<string, string>;\n\n  /**\n   * List of Vercel Regions where the Vercel Function will be deployed to.\n   */\n  regions?: string[];\n\n  /**\n   * True if a custom runtime has support for Lambda runtime wrappers.\n   */\n  supportsWrapper?: boolean;\n\n  /**\n   * When true, the Serverless Function will stream the response to the client.\n   */\n  supportsResponseStreaming?: boolean;\n\n  /**\n   * Enables source map generation.\n   */\n  shouldAddSourcemapSupport?: boolean;\n\n  /**\n   * The runtime to use. Defaults to the auto-detected Node.js version.\n   */\n  runtime?: \"nodejs20.x\" | \"nodejs22.x\" | \"bun1.x\" | (string & {});\n\n  [key: string]: unknown;\n}\n\nexport interface VercelOptions {\n  config?: VercelBuildConfigV3;\n\n  /**\n   * If you have enabled skew protection in the Vercel dashboard, it will\n   * be enabled by default.\n   *\n   * You can disable the Nitro integration by setting this option to `false`.\n   */\n  skewProtection?: boolean;\n\n  /**\n   * If you are using `vercel-edge`, you can specify the region(s) for your edge function.\n   * @see https://vercel.com/docs/concepts/functions/edge-functions#edge-function-regions\n   */\n  regions?: string[];\n\n  functions?: VercelServerlessFunctionConfig;\n\n  /**\n   * Handler format to use for Vercel Serverless Functions.\n   *\n   * Using `node` format enables compatibility with Node.js specific APIs in your Nitro application (e.g., `req.runtime.node`).\n   *\n   * Possible values are: `web` (default) and `node`.\n   */\n  entryFormat?: \"web\" | \"node\";\n\n  /**\n   * The route path for the Vercel cron handler endpoint.\n   *\n   * When `experimental.tasks` and `scheduledTasks` are configured,\n   * Nitro registers a cron handler at this path that Vercel invokes\n   * on each scheduled cron trigger.\n   *\n   * @default \"/_vercel/cron\"\n   * @see https://vercel.com/docs/cron-jobs\n   */\n  cronHandlerRoute?: string;\n}\n\n/**\n * https://vercel.com/docs/build-output-api/v3/primitives#prerender-configuration-file\n */\nexport type PrerenderFunctionConfig = {\n  /**\n   * Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to `false` means it will never expire.\n   */\n  expiration: number | false;\n\n  /**\n   * Option group number of the asset. Prerender assets with the same group number will all be re-validated at the same time.\n   */\n  group?: number;\n\n  /** Random token assigned to the `__prerender_bypass` cookie when Draft Mode is enabled, in order to safely bypass the Edge Network cache */\n  bypassToken?: string;\n\n  /**\n   * Name of the optional fallback file relative to the configuration file.\n   */\n  fallback?: string;\n\n  /**\n   * List of query string parameter names that will be cached independently. If an empty array, query values are not considered for caching. If undefined each unique query value is cached independently\n   */\n  allowQuery?: string[];\n\n  /**\n   * When `true`, the query string will be present on the `request` argument passed to the invoked function. The `allowQuery` filter still applies.\n   */\n  passQuery?: boolean;\n\n  /**\n   * (vercel)\n   *\n   * When `true`, expose the response body regardless of status code including error status codes. (default `false`)\n   */\n  exposeErrBody?: boolean;\n};\n"
  },
  {
    "path": "src/presets/vercel/utils.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport { defu } from \"defu\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport type { Nitro, NitroRouteRules } from \"nitro/types\";\nimport { dirname, relative, resolve } from \"pathe\";\nimport { joinURL, withLeadingSlash, withoutLeadingSlash } from \"ufo\";\nimport type {\n  PrerenderFunctionConfig,\n  VercelBuildConfigV3,\n  VercelServerlessFunctionConfig,\n} from \"./types.ts\";\nimport { isTest } from \"std-env\";\nimport { ISR_URL_PARAM } from \"./runtime/isr.ts\";\n\n// https://vercel.com/docs/build-output-api/configuration\n\n// https://vercel.com/docs/functions/runtimes/node-js/node-js-versions\nconst SUPPORTED_NODE_VERSIONS = [20, 22, 24];\n\n// h3 ProxyOptions that Vercel CDN rewrites cannot handle at the edge.\n// https://vercel.com/docs/rewrites\nconst UNSUPPORTED_PROXY_OPTIONS = [\n  \"headers\", // headers added to the outgoing request to the upstream\n  \"forwardHeaders\",\n  \"filterHeaders\",\n  \"fetchOptions\",\n  \"cookieDomainRewrite\",\n  \"cookiePathRewrite\",\n  \"onResponse\",\n] as const;\n\nconst FALLBACK_ROUTE = \"/__server\";\n\nconst ISR_SUFFIX = \"-isr\"; // Avoid using . as it can conflict with routing\n\nconst SAFE_FS_CHAR_RE = /[^a-zA-Z0-9_.[\\]/]/g;\n\nfunction getSystemNodeVersion() {\n  const systemNodeVersion = Number.parseInt(process.versions.node.split(\".\")[0]);\n\n  return Number.isNaN(systemNodeVersion) ? 22 : systemNodeVersion;\n}\n\nexport async function generateFunctionFiles(nitro: Nitro) {\n  const o11Routes = getObservabilityRoutes(nitro);\n\n  const buildConfigPath = resolve(nitro.options.output.dir, \"config.json\");\n  const buildConfig = generateBuildConfig(nitro, o11Routes);\n  await writeFile(buildConfigPath, JSON.stringify(buildConfig, null, 2));\n\n  const functionConfigPath = resolve(nitro.options.output.serverDir, \".vc-config.json\");\n  const functionConfig: VercelServerlessFunctionConfig = {\n    handler: \"index.mjs\",\n    launcherType: \"Nodejs\",\n    shouldAddHelpers: false,\n    supportsResponseStreaming: true,\n    ...nitro.options.vercel?.functions,\n  };\n  await writeFile(functionConfigPath, JSON.stringify(functionConfig, null, 2));\n\n  // Write ISR functions\n  for (const [key, value] of Object.entries(nitro.options.routeRules)) {\n    if (!value.isr) {\n      continue;\n    }\n\n    const funcPrefix = resolve(\n      nitro.options.output.serverDir,\n      \"..\",\n      normalizeRouteDest(key) + ISR_SUFFIX\n    );\n    await fsp.mkdir(dirname(funcPrefix), { recursive: true });\n    await fsp.symlink(\n      \"./\" + relative(dirname(funcPrefix), nitro.options.output.serverDir),\n      funcPrefix + \".func\",\n      \"junction\"\n    );\n    await writePrerenderConfig(\n      funcPrefix + \".prerender-config.json\",\n      value.isr,\n      nitro.options.vercel?.config?.bypassToken\n    );\n  }\n\n  // Write observability routes\n  if (o11Routes.length === 0) {\n    return;\n  }\n  const _getRouteRules = (path: string) =>\n    defu({}, ...nitro.routing.routeRules.matchAll(\"\", path).reverse()) as NitroRouteRules;\n  for (const route of o11Routes) {\n    const routeRules = _getRouteRules(route.src);\n    if (routeRules.isr) {\n      continue; // #3563\n    }\n    const funcPrefix = resolve(nitro.options.output.serverDir, \"..\", route.dest);\n    await fsp.mkdir(dirname(funcPrefix), { recursive: true });\n    await fsp.symlink(\n      \"./\" + relative(dirname(funcPrefix), nitro.options.output.serverDir),\n      funcPrefix + \".func\",\n      \"junction\"\n    );\n  }\n}\n\nexport async function generateEdgeFunctionFiles(nitro: Nitro) {\n  const buildConfigPath = resolve(nitro.options.output.dir, \"config.json\");\n  const buildConfig = generateBuildConfig(nitro);\n  await writeFile(buildConfigPath, JSON.stringify(buildConfig, null, 2));\n\n  const functionConfigPath = resolve(nitro.options.output.serverDir, \".vc-config.json\");\n  const functionConfig = {\n    runtime: \"edge\",\n    entrypoint: \"index.mjs\",\n    regions: nitro.options.vercel?.regions,\n  };\n  await writeFile(functionConfigPath, JSON.stringify(functionConfig, null, 2));\n}\n\nexport async function generateStaticFiles(nitro: Nitro) {\n  const buildConfigPath = resolve(nitro.options.output.dir, \"config.json\");\n  const buildConfig = generateBuildConfig(nitro);\n  await writeFile(buildConfigPath, JSON.stringify(buildConfig, null, 2));\n}\n\nfunction generateBuildConfig(nitro: Nitro, o11Routes?: ObservabilityRoute[]) {\n  const rules = Object.entries(nitro.options.routeRules).sort(\n    (a, b) => b[0].split(/\\/(?!\\*)/).length - a[0].split(/\\/(?!\\*)/).length\n  );\n\n  // Determine which proxy rules can be offloaded to Vercel CDN rewrites\n  const cdnProxyPaths = new Set(\n    rules\n      .filter(([_, routeRules]) => routeRules.proxy && canUseVercelRewrite(routeRules.proxy))\n      .map(([path]) => path)\n  );\n\n  const config = defu(nitro.options.vercel?.config, {\n    version: 3,\n    framework: {\n      name: nitro.options.framework.name,\n      version: nitro.options.framework.version,\n    },\n    overrides: {\n      // Nitro static prerendered route overrides\n      ...Object.fromEntries(\n        (nitro._prerenderedRoutes?.filter((r) => r.fileName !== r.route) || []).map(\n          ({ route, fileName }) => [\n            withoutLeadingSlash(fileName),\n            { path: route.replace(/^\\//, \"\") },\n          ]\n        )\n      ),\n    },\n    routes: [\n      // Redirect and header rules (excluding paths handled as CDN proxy rewrites)\n      ...rules\n        .filter(\n          ([path, routeRules]) =>\n            (routeRules.redirect || routeRules.headers) && !cdnProxyPaths.has(path)\n        )\n        .map(([path, routeRules]) => {\n          let route = {\n            src: path.replace(\"/**\", \"/(.*)\"),\n          };\n          if (routeRules.redirect) {\n            route = defu(route, {\n              status: routeRules.redirect.status,\n              headers: {\n                Location: routeRules.redirect.to.replace(\"/**\", \"/$1\"),\n              },\n            });\n          }\n          if (routeRules.headers) {\n            route = defu(route, { headers: routeRules.headers });\n          }\n          return route;\n        }),\n      // Proxy rewrite rules (CDN-level reverse proxy)\n      // https://vercel.com/docs/rewrites\n      ...rules\n        .filter(([path]) => cdnProxyPaths.has(path))\n        .map(([path, routeRules]) => {\n          const proxy = routeRules.proxy!;\n          const route: Record<string, any> = {\n            src: path.replace(\"/**\", \"/(.*)\"),\n            dest: proxy.to.replace(\"/**\", \"/$1\"),\n          };\n          if (routeRules.headers) {\n            route.headers = routeRules.headers;\n          }\n          return route;\n        }),\n      // Skew protection\n      ...(nitro.options.vercel?.skewProtection && nitro.options.manifest?.deploymentId\n        ? [\n            {\n              src: \"/.*\",\n              has: [\n                {\n                  type: \"header\",\n                  key: \"Sec-Fetch-Dest\",\n                  value: \"document\",\n                },\n              ],\n              headers: {\n                \"Set-Cookie\": `__vdpl=${nitro.options.manifest.deploymentId}; Path=${nitro.options.baseURL}; SameSite=Strict; Secure; HttpOnly`,\n              },\n              continue: true,\n            },\n          ]\n        : []),\n      // Public asset rules\n      ...nitro.options.publicAssets\n        .filter((asset) => !asset.fallthrough)\n        .map((asset) => joinURL(nitro.options.baseURL, asset.baseURL || \"/\"))\n        .map((baseURL) => ({\n          src: baseURL + \"(.*)\",\n          headers: {\n            \"cache-control\": \"public,max-age=31536000,immutable\",\n          },\n          continue: true,\n        })),\n      { handle: \"filesystem\" },\n    ],\n  } as VercelBuildConfigV3);\n\n  // Cron jobs from scheduledTasks\n  if (\n    nitro.options.experimental.tasks &&\n    Object.keys(nitro.options.scheduledTasks || {}).length > 0\n  ) {\n    const cronPath = nitro.options.vercel!.cronHandlerRoute || \"/_vercel/cron\";\n    const cronEntries = Object.keys(nitro.options.scheduledTasks).map((schedule) => ({\n      path: cronPath,\n      schedule,\n    }));\n    config.crons = [...cronEntries, ...(config.crons || [])];\n  }\n\n  // Early return if we are building a static site\n  if (nitro.options.static) {\n    return config;\n  }\n\n  config.routes!.push(\n    // ISR rules\n    // ...If we are using an ISR function for /, then we need to write this explicitly\n    ...(nitro.options.routeRules[\"/\"]?.isr\n      ? [\n          {\n            src: `(?<${ISR_URL_PARAM}>/)`,\n            dest: `/index${ISR_SUFFIX}?${ISR_URL_PARAM}=$${ISR_URL_PARAM}`,\n          },\n        ]\n      : []),\n    // ...Add rest of the ISR routes\n    ...rules\n      .filter(([key, value]) => value.isr !== undefined && key !== \"/\")\n      .map(([key, value]) => {\n        const src = `(?<${ISR_URL_PARAM}>${normalizeRouteSrc(key)})`;\n        if (value.isr === false) {\n          // We need to write a rule to avoid route being shadowed by another cache rule elsewhere\n          return {\n            src,\n            dest: FALLBACK_ROUTE,\n          };\n        }\n        return {\n          src,\n          dest: withLeadingSlash(\n            normalizeRouteDest(key) + ISR_SUFFIX + `?${ISR_URL_PARAM}=$${ISR_URL_PARAM}`\n          ),\n        };\n      }),\n    // Observability routes\n    ...(o11Routes || []).map((route) => ({\n      src: joinURL(nitro.options.baseURL, route.src),\n      dest: withLeadingSlash(route.dest),\n    })),\n    // If we are using an ISR function as a fallback\n    // then we do not need to output the below fallback route as well\n    ...(nitro.options.routeRules[\"/**\"]?.isr\n      ? []\n      : [\n          {\n            src: \"/(.*)\",\n            dest: FALLBACK_ROUTE,\n          },\n        ])\n  );\n\n  return config;\n}\n\nexport function deprecateSWR(nitro: Nitro) {\n  if (nitro.options.future.nativeSWR) {\n    return;\n  }\n  let hasLegacyOptions = false;\n  for (const [_key, value] of Object.entries(nitro.options.routeRules)) {\n    if (_hasProp(value, \"isr\")) {\n      continue;\n    }\n    if (value.cache === false) {\n      value.isr = false;\n    }\n    if (_hasProp(value, \"static\")) {\n      value.isr = !(value as { static: boolean }).static;\n      hasLegacyOptions = true;\n    }\n    if (value.cache && _hasProp(value.cache, \"swr\")) {\n      value.isr = value.cache.swr;\n      hasLegacyOptions = true;\n    }\n  }\n  if (hasLegacyOptions && !isTest) {\n    nitro.logger.warn(\n      \"Nitro now uses `isr` option to configure ISR behavior on Vercel. Backwards-compatible support for `static` and `swr` options within the Vercel Build Options API will be removed in the future versions. Set `future.nativeSWR: true` nitro config disable this warning.\"\n    );\n  }\n}\n\n// --- vercel.json ---\n\n// https://vercel.com/docs/project-configuration\n// https://openapi.vercel.sh/vercel.json\nexport interface VercelConfig {\n  bunVersion?: string;\n}\n\nexport async function resolveVercelRuntime(nitro: Nitro) {\n  // 1. Respect explicit runtime from nitro config\n  let runtime: VercelServerlessFunctionConfig[\"runtime\"] = nitro.options.vercel?.functions?.runtime;\n\n  if (runtime) {\n    // Already specified\n    return runtime;\n  }\n\n  // 2. Read runtime from vercel.json if specified\n  const vercelConfig = await readVercelConfig(nitro.options.rootDir);\n\n  // 3. Use bun runtime if bunVersion is specified or bun used to build\n  if (vercelConfig.bunVersion || \"Bun\" in globalThis) {\n    runtime = \"bun1.x\";\n  } else {\n    // 3. Auto-detect runtime based on system Node.js version\n    const systemNodeVersion = getSystemNodeVersion();\n    const usedNodeVersion =\n      SUPPORTED_NODE_VERSIONS.find((version) => version >= systemNodeVersion) ??\n      SUPPORTED_NODE_VERSIONS.at(-1);\n    runtime = `nodejs${usedNodeVersion}.x`;\n  }\n\n  // Synchronize back to nitro config\n  nitro.options.vercel ??= {} as any;\n  nitro.options.vercel!.functions ??= {} as any;\n  nitro.options.vercel!.functions!.runtime = runtime;\n\n  return runtime;\n}\n\nexport async function readVercelConfig(rootDir: string): Promise<VercelConfig> {\n  const vercelConfigPath = resolve(rootDir, \"vercel.json\");\n  const vercelConfig = await fsp\n    .readFile(vercelConfigPath)\n    .then((config) => JSON.parse(config.toString()))\n    .catch(() => ({}));\n  return vercelConfig as VercelConfig;\n}\n\nfunction _hasProp(obj: any, prop: string) {\n  return obj && typeof obj === \"object\" && prop in obj;\n}\n\n/**\n * Check if a proxy rule can be offloaded to a Vercel CDN rewrite.\n * A proxy is eligible when it targets an external URL and uses no\n * ProxyOptions that Vercel's routing layer cannot handle at the edge.\n */\nfunction canUseVercelRewrite(proxy: NitroRouteRules[\"proxy\"]): proxy is { to: string } {\n  if (!proxy?.to) {\n    return false;\n  }\n  // Must be an external URL\n  if (!/^https?:\\/\\//.test(proxy.to.replace(/\\/\\*\\*$/, \"\"))) {\n    return false;\n  }\n  // Must not use any ProxyOptions unsupported by Vercel rewrites\n  for (const key of UNSUPPORTED_PROXY_OPTIONS) {\n    if ((proxy as any)[key] !== undefined) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// --- utils for observability ---\n\ntype ObservabilityRoute = {\n  src: string; // route pattern\n  dest: string; // function name\n};\n\nfunction getObservabilityRoutes(nitro: Nitro): ObservabilityRoute[] {\n  const compatDate =\n    nitro.options.compatibilityDate.vercel || nitro.options.compatibilityDate.default;\n  if (compatDate < \"2025-07-15\") {\n    return [];\n  }\n\n  // Sort routes by how much specific they are\n  const routePatterns = [\n    ...new Set([\n      ...(nitro.options.ssrRoutes || []),\n      ...[...nitro.scannedHandlers, ...nitro.options.handlers]\n        .filter((h) => !h.middleware && h.route)\n        .map((h) => h.route!),\n    ]),\n  ];\n\n  const staticRoutes: string[] = [];\n  const dynamicRoutes: string[] = [];\n  const catchAllRoutes: string[] = [];\n\n  for (const route of routePatterns) {\n    if (route.includes(\"**\")) {\n      catchAllRoutes.push(route);\n    } else if (route.includes(\":\") || route.includes(\"*\")) {\n      dynamicRoutes.push(route);\n    } else {\n      staticRoutes.push(route);\n    }\n  }\n\n  return [\n    ...normalizeRoutes(staticRoutes),\n    ...normalizeRoutes(dynamicRoutes),\n    ...normalizeRoutes(catchAllRoutes),\n  ];\n}\n\nfunction normalizeRoutes(routes: string[]) {\n  return routes\n    .sort((a, b) =>\n      // a.split(\"/\").length - b.split(\"/\").length ||\n      b.localeCompare(a)\n    )\n    .map((route) => ({\n      src: normalizeRouteSrc(route),\n      dest: normalizeRouteDest(route),\n    }));\n}\n\n// Input is a rou3/radix3 compatible route pattern\n// Output is a PCRE-compatible regular expression that matches each incoming pathname\n// Reference: https://github.com/h3js/rou3/blob/main/src/regexp.ts\nfunction normalizeRouteSrc(route: string): string {\n  let idCtr = 0;\n  return route\n    .split(\"/\")\n    .map((segment) => {\n      if (segment.startsWith(\"**\")) {\n        return segment === \"**\" ? \"(?:.*)\" : `?(?<${namedGroup(segment.slice(3))}>.+)`;\n      }\n      if (segment === \"*\") {\n        return `(?<_${idCtr++}>[^/]*)`;\n      }\n      if (segment.includes(\":\")) {\n        return segment\n          .replace(/:(\\w+)/g, (_, id) => `(?<${namedGroup(id)}>[^/]+)`)\n          .replace(/\\./g, String.raw`\\.`);\n      }\n      return segment;\n    })\n    .join(\"/\");\n}\n\n// Valid PCRE capture group name\nfunction namedGroup(input = \"\") {\n  if (/\\d/.test(input[0])) {\n    input = `_${input}`;\n  }\n  return input.replace(/[^a-zA-Z0-9_]/g, \"\") || \"_\";\n}\n\n// Output is a destination pathname to function name\nfunction normalizeRouteDest(route: string) {\n  return (\n    route\n      .split(\"/\")\n      .slice(1)\n      .map((segment) => {\n        if (segment.startsWith(\"**\")) {\n          return `[...${segment.replace(/[*:]/g, \"\")}]`;\n        }\n        if (segment === \"*\") {\n          return \"[-]\";\n        }\n        if (segment.startsWith(\":\")) {\n          return `[${segment.slice(1)}]`;\n        }\n        if (segment.includes(\":\")) {\n          return `[${segment.replace(/:/g, \"_\")}]`;\n        }\n        return segment;\n      })\n      // Only use filesystem-safe characters\n      .map((segment) => segment.replace(SAFE_FS_CHAR_RE, \"-\"))\n      .join(\"/\") || \"index\"\n  );\n}\n\nasync function writePrerenderConfig(\n  filename: string,\n  isrConfig: NitroRouteRules[\"isr\"],\n  bypassToken?: string\n) {\n  // Normalize route rule\n  if (typeof isrConfig === \"number\") {\n    isrConfig = { expiration: isrConfig };\n  } else if (isrConfig === true) {\n    isrConfig = { expiration: false };\n  } else {\n    isrConfig = { ...isrConfig };\n  }\n\n  // Generate prerender config\n  const prerenderConfig: PrerenderFunctionConfig = {\n    expiration: isrConfig.expiration ?? false,\n    bypassToken,\n    ...isrConfig,\n  };\n\n  if (prerenderConfig.allowQuery && !prerenderConfig.allowQuery.includes(ISR_URL_PARAM)) {\n    prerenderConfig.allowQuery.push(ISR_URL_PARAM);\n  }\n\n  await writeFile(filename, JSON.stringify(prerenderConfig, null, 2));\n}\n"
  },
  {
    "path": "src/presets/winterjs/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst winterjs = defineNitroPreset(\n  {\n    extends: \"base-worker\",\n    entry: \"./winterjs/runtime/winterjs\",\n    minify: false,\n    serveStatic: \"inline\",\n    wasm: {\n      lazy: true,\n    },\n    commands: {\n      preview:\n        \"wasmer run wasmer/winterjs --forward-host-env --net --mapdir app:./ app/server/index.mjs\",\n    },\n  },\n  {\n    name: \"winterjs\" as const,\n  }\n);\n\nexport default [winterjs] as const;\n"
  },
  {
    "path": "src/presets/winterjs/runtime/winterjs.ts",
    "content": "// @ts-nocheck TODO: Remove after removing polyfills\nimport \"#nitro/virtual/polyfills\";\nimport { useNitroApp } from \"nitro/app\";\nimport { hasProtocol, joinURL } from \"ufo\";\n\n// Types are reverse engineered from runtime\n\ninterface ExecuteRequest {\n  url: URL;\n  body?: ReadableStream;\n  bodyUsed: boolean;\n  headers: Headers;\n  getMethod: () => string;\n}\n\ninterface FetchEvent extends Event {\n  request: ExecuteRequest;\n  respondWith(response: Promise<Response> | Response): Promise<Response>;\n  waitUntil: (promise: Promise<any>) => void;\n}\n\nconst nitroApp = useNitroApp();\n\n// Use plain handler as winterjs Web API is incomplete\n// TODO: Migrate to toWebHandler\nconst _handler = toPlainHandler(nitroApp.h3App);\n\nasync function _handleEvent(event: FetchEvent) {\n  try {\n    const res = await _handler({\n      path:\n        event.request.url.pathname +\n        (event.request.url.search ? `?${event.request.url.search}` : \"\"),\n      method: event.request.getMethod() || \"GET\",\n      body: event.request.body,\n      headers: event.request.headers,\n      context: {\n        waitUntil: (promise: Promise<any>) => event.waitUntil(promise),\n        _platform: {\n          winterjs: {\n            event,\n          },\n        },\n      },\n    });\n    const body = typeof res.body === \"string\" ? res.body : await toBuffer(res.body as any);\n    return new Response(body, {\n      status: res.status,\n      statusText: res.statusText,\n      headers: res.headers,\n    });\n  } catch (error: unknown) {\n    const errString = (error as Error)?.message + \"\\n\" + (error as Error)?.stack;\n    console.error(errString);\n    return new Response(errString, { status: 500 });\n  }\n}\n\naddEventListener(\"fetch\" as any, async (event: FetchEvent) => {\n  event.respondWith(await _handleEvent(event));\n});\n\n// ------------------------------\n// Polyfills for missing APIs\n// ------------------------------\n\nfunction toBuffer(data: ReadableStream): Promise<Buffer> {\n  return new Promise<Buffer>((resolve, reject) => {\n    const chunks: Buffer[] = [];\n    data\n      .pipeTo(\n        new WritableStream({\n          write(chunk) {\n            chunks.push(chunk);\n          },\n          close() {\n            resolve(Buffer.concat(chunks));\n          },\n          abort(reason) {\n            reject(reason);\n          },\n        })\n      )\n      .catch(reject);\n  });\n}\n\n// Headers.entries\nif (!Headers.prototype.entries) {\n  // @ts-ignore\n  Headers.prototype.entries = function () {\n    return [...this];\n  };\n}\n\n// URL.pathname\nif (!URL.prototype.pathname) {\n  Object.defineProperty(URL.prototype, \"pathname\", {\n    get() {\n      return this.path || \"/\";\n    },\n  });\n}\n\n// URL constructor (relative support)\nconst _URL = globalThis.URL;\nglobalThis.URL = class URL extends _URL {\n  constructor(url: string | URL, base: string | URL) {\n    if (!base || hasProtocol(url)) {\n      super(url);\n      return;\n    }\n    super(joinURL(base, url));\n  }\n};\n\n// Response (avoid Promise body)\nconst _Response = globalThis.Response;\nglobalThis.Response = class Response extends _Response {\n  _body: BodyInit;\n\n  constructor(body, init) {\n    super(body, init);\n    this._body = body;\n  }\n\n  get body() {\n    // TODO: Return ReadableStream (should be iterable)\n    return this._body as any;\n  }\n};\n"
  },
  {
    "path": "src/presets/zeabur/preset.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport { writeFile } from \"../_utils/fs.ts\";\nimport { defineNitroPreset } from \"../_utils/preset.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { dirname, relative, resolve } from \"pathe\";\n\n// https://zeabur.com/docs/advanced/serverless-output-format\n\nconst zeabur = defineNitroPreset(\n  {\n    entry: \"./zeabur/runtime/zeabur\",\n    output: {\n      dir: \"{{ rootDir }}/.zeabur/output\",\n      serverDir: \"{{ output.dir }}/functions/__nitro.func\",\n      publicDir: \"{{ output.dir }}/static\",\n    },\n    hooks: {\n      async compiled(nitro: Nitro) {\n        const buildConfigPath = resolve(nitro.options.output.dir, \"config.json\");\n        const cfg = {\n          containerized: false,\n          routes: [{ src: \".*\", dest: \"/__nitro\" }],\n        };\n        await writeFile(buildConfigPath, JSON.stringify(cfg, null, 2));\n\n        // Write ISR functions\n        for (const [key, value] of Object.entries(nitro.options.routeRules)) {\n          if (!value.isr) {\n            continue;\n          }\n          const funcPrefix = resolve(nitro.options.output.serverDir, \"..\" + key);\n          await fsp.mkdir(dirname(funcPrefix), { recursive: true });\n          await fsp.symlink(\n            \"./\" + relative(dirname(funcPrefix), nitro.options.output.serverDir),\n            funcPrefix + \".func\",\n            \"junction\"\n          );\n          await writeFile(\n            funcPrefix + \".prerender-config.json\",\n            JSON.stringify({ type: \"Prerender\" })\n          );\n        }\n      },\n    },\n  },\n  {\n    name: \"zeabur\" as const,\n    stdName: \"zeabur\",\n  }\n);\n\nconst zeaburStatic = defineNitroPreset(\n  {\n    extends: \"static\",\n    output: {\n      dir: \"{{ rootDir }}/.zeabur/output\",\n      publicDir: \"{{ output.dir }}/static\",\n    },\n    commands: {\n      preview: \"npx serve ./static\",\n    },\n  },\n  {\n    name: \"zeabur-static\" as const,\n\n    static: true,\n  }\n);\n\nexport default [zeabur, zeaburStatic] as const;\n"
  },
  {
    "path": "src/presets/zeabur/runtime/zeabur.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { toNodeHandler } from \"srvx/node\";\nimport { useNitroApp } from \"nitro/app\";\n\nexport default toNodeHandler(useNitroApp().fetch);\n"
  },
  {
    "path": "src/presets/zephyr/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\nimport type { Nitro } from \"nitro/types\";\nimport { unenvCfExternals, unenvCfNodeCompat } from \"../cloudflare/unenv/preset.ts\";\nimport { resolve } from \"pathe\";\nimport { importDep } from \"../../utils/dep.ts\";\n\nexport type { ZephyrOptions as PresetOptions } from \"./types.ts\";\nconst LOGGER_TAG = \"zephyr-nitro-preset\";\ntype ZephyrAgentModule = Pick<typeof import(\"zephyr-agent\"), \"uploadOutputToZephyr\">;\n\nconst zephyr = defineNitroPreset(\n  {\n    extends: \"base-worker\",\n    entry: \"./zephyr/runtime/server\",\n    output: {\n      publicDir: \"{{ output.dir }}/client/{{ baseURL }}\",\n    },\n    exportConditions: [\"node\"],\n    minify: false,\n    rollupConfig: {\n      output: {\n        format: \"esm\",\n        exports: \"named\",\n        inlineDynamicImports: false,\n      },\n    },\n    wasm: {\n      lazy: false,\n      esmImport: true,\n    },\n    hooks: {\n      \"build:before\": (nitro: Nitro) => {\n        nitro.options.unenv.push(unenvCfExternals, unenvCfNodeCompat);\n      },\n      compiled: async (nitro: Nitro) => {\n        try {\n          if (!(globalThis as any).__nitroDeploying__ && !nitro.options.zephyr?.deployOnBuild) {\n            nitro.logger.info(`[${LOGGER_TAG}] Zephyr deploy skipped on build.`);\n            return;\n          }\n\n          const zephyrAgent = await importDep<ZephyrAgentModule>({\n            id: \"zephyr-agent\",\n            reason: \"deploying to Zephyr\",\n            dir: nitro.options.rootDir,\n          });\n\n          const { deploymentUrl } = await zephyrAgent.uploadOutputToZephyr({\n            rootDir: nitro.options.rootDir,\n            outputDir: nitro.options.output.dir,\n            baseURL: nitro.options.baseURL,\n            publicDir: resolve(nitro.options.output.dir, nitro.options.output.publicDir),\n          });\n          if (deploymentUrl) {\n            nitro.logger.success(`[${LOGGER_TAG}] Zephyr deployment succeeded: ${deploymentUrl}`);\n          } else {\n            nitro.logger.success(`[${LOGGER_TAG}] Zephyr deployment succeeded.`);\n          }\n\n          (globalThis as any).__nitroDeployed__ = true;\n        } catch (error) {\n          if (error instanceof Error) {\n            throw error;\n          }\n          throw new TypeError(`[${LOGGER_TAG}] ${String(error)}`);\n        }\n      },\n    },\n  },\n  {\n    name: \"zephyr\" as const,\n  }\n);\n\nexport default [zephyr] as const;\n"
  },
  {
    "path": "src/presets/zephyr/runtime/server.ts",
    "content": "import \"#nitro/virtual/polyfills\";\nimport { createHandler } from \"../../cloudflare/runtime/_module-handler.ts\";\n\nexport default createHandler({\n  fetch() {},\n});\n"
  },
  {
    "path": "src/presets/zephyr/types.ts",
    "content": "export interface ZephyrOptions {\n  /**\n   * Deploy to Zephyr during `nitro build` when using the `zephyr` preset.\n   *\n   * @default false\n   */\n  deployOnBuild?: boolean;\n}\n"
  },
  {
    "path": "src/presets/zerops/preset.ts",
    "content": "import { defineNitroPreset } from \"../_utils/preset.ts\";\n\nconst zerops = defineNitroPreset(\n  {\n    extends: \"node-server\",\n    serveStatic: true,\n  },\n  {\n    name: \"zerops\" as const,\n  }\n);\n\nconst zeropsStatic = defineNitroPreset(\n  {\n    extends: \"static\",\n    output: {\n      dir: \"{{ rootDir }}/.zerops/output\",\n      publicDir: \"{{ output.dir }}/static\",\n    },\n  },\n  {\n    name: \"zerops-static\" as const,\n\n    static: true,\n  }\n);\n\nexport default [zerops, zeropsStatic] as const;\n"
  },
  {
    "path": "src/preview.ts",
    "content": "import type { ServerHandler, ServerRequest } from \"srvx\";\nimport type { LoadOptions } from \"srvx/loader\";\nimport { spawn } from \"node:child_process\";\nimport consola from \"consola\";\nimport { join, resolve } from \"pathe\";\nimport { proxyFetch, proxyUpgrade, type ProxyUpgradeOptions } from \"httpxy\";\nimport { prettyPath } from \"./utils/fs.ts\";\nimport { getBuildInfo } from \"./build/info.ts\";\nimport type { IncomingMessage } from \"node:http\";\nimport type { Duplex } from \"node:stream\";\n\nexport interface PreviewInstance {\n  fetch: ServerHandler;\n  upgrade?: (\n    req: IncomingMessage,\n    socket: Duplex,\n    head?: Buffer,\n    opts?: ProxyUpgradeOptions\n  ) => Promise<void>;\n  close: () => Promise<void>;\n}\n\nexport async function startPreview(opts: {\n  rootDir: string;\n  loader?: LoadOptions;\n}): Promise<PreviewInstance> {\n  const { outputDir, buildInfo } = await getBuildInfo(opts.rootDir);\n  if (!buildInfo) {\n    throw new Error(\"Cannot load nitro build info. Make sure to build first.\");\n  }\n\n  const info = [\n    [\"Build Directory:\", prettyPath(outputDir)],\n    [\"Date:\", buildInfo.date && new Date(buildInfo.date).toLocaleString()],\n    [\"Nitro Version:\", buildInfo.versions.nitro],\n    [\"Nitro Preset:\", buildInfo.preset],\n    buildInfo.framework?.name !== \"nitro\" && [\n      \"Framework:\",\n      buildInfo.framework?.name +\n        (buildInfo.framework?.version ? ` (v${buildInfo.framework.version})` : \"\"),\n    ],\n  ].filter((i) => i && i[1]) as [string, string][];\n  consola.box({\n    title: \" [Build Info] \",\n    message: info.map((i) => `- ${i[0]} ${i[1]}`).join(\"\\n\"),\n  });\n\n  // Load .env files for preview mode\n  const dotEnvEntries = await loadPreviewDotEnv(opts.rootDir);\n  if (dotEnvEntries.length > 0) {\n    consola.box({\n      title: \" [Environment Variables] \",\n      message: [\n        \"Loaded variables from .env files (preview mode only).\",\n        \"Set platform environment variables for production:\",\n        ...dotEnvEntries.map(([key, val]) => ` - ${key}`),\n      ].join(\"\\n\"),\n    });\n  }\n\n  // Currently cloudflare preset strictly requires preview command\n  if (buildInfo.preset.includes(\"cloudflare\")) {\n    if (!buildInfo.commands?.preview) {\n      throw new Error(`No nitro build preview command found for the \"${buildInfo.preset}\" preset.`);\n    }\n    return await runPreviewCommand({\n      command: buildInfo.commands.preview,\n      rootDir: opts.rootDir,\n      env: dotEnvEntries,\n    });\n  }\n\n  let fetchHandler: ServerHandler = () =>\n    Promise.resolve(new Response(\"Not Found\", { status: 404 }));\n\n  if (buildInfo.serverEntry) {\n    for (const [key, val] of dotEnvEntries) {\n      if (!process.env[key]) {\n        process.env[key] = val;\n      }\n    }\n    const { loadServerEntry } = await import(\"srvx/loader\");\n    const entryPath = resolve(outputDir, buildInfo.serverEntry);\n    const entry = await loadServerEntry({ entry: entryPath, ...opts.loader });\n    if (entry.fetch) {\n      fetchHandler = entry.fetch;\n    }\n  }\n\n  if (buildInfo.publicDir) {\n    const { serveStatic } = await import(\"srvx/static\");\n    const staticHandler = serveStatic({ dir: join(outputDir, buildInfo.publicDir) });\n    const originalFetchHandler = fetchHandler;\n    fetchHandler = async (req) => {\n      const staticRes: Response | undefined = await staticHandler(req, () => undefined as any);\n      if (staticRes) {\n        return staticRes;\n      }\n      return originalFetchHandler(req);\n    };\n  }\n\n  return {\n    fetch: fetchHandler,\n    async close() {\n      // No-op for in-process preview for now\n    },\n  };\n}\n\nasync function loadPreviewDotEnv(root: string): Promise<[string, string][]> {\n  const { loadDotenv } = await import(\"c12\");\n  const env = await loadDotenv({\n    cwd: root,\n    fileName: [\".env.preview\", \".env.production\", \".env\"],\n  });\n  return Object.entries(env).filter(([_key, val]) => val) as [string, string][];\n}\n\nasync function runPreviewCommand(opts: {\n  command: string;\n  rootDir: string;\n  env: [string, string][];\n}): Promise<PreviewInstance> {\n  const [arg0, ...args] = opts.command.split(\" \");\n\n  consola.info(`Spawning preview server...`);\n  consola.info(opts.command);\n  console.log(\"\");\n\n  const { getRandomPort, waitForPort } = await import(\"get-port-please\");\n  const randomPort = await getRandomPort();\n  const child = spawn(arg0, [...args, \"--port\", String(randomPort), \"--host\", \"localhost\"], {\n    stdio: \"inherit\",\n    cwd: opts.rootDir,\n    env: {\n      ...process.env,\n      ...Object.fromEntries(opts.env ?? []),\n      PORT: String(randomPort),\n    },\n  });\n\n  const killChild = (signal: NodeJS.Signals) => {\n    if (child && !child.killed) {\n      child.kill(signal);\n    }\n  };\n\n  for (const sig of [\"SIGINT\", \"SIGHUP\"] as const) {\n    process.once(sig, () => {\n      killChild(sig);\n    });\n  }\n\n  child.once(\"exit\", (code) => {\n    if (code && code !== 0) {\n      consola.error(`[nitro] Preview server exited with code ${code}`);\n    }\n  });\n\n  await waitForPort(randomPort, { retries: 20, delay: 500, host: \"localhost\" });\n\n  return {\n    fetch(req: ServerRequest) {\n      return proxyFetch({ port: randomPort, host: \"localhost\" }, req);\n    },\n    async upgrade(req, socket, head, opts) {\n      await proxyUpgrade({ port: randomPort, host: \"localhost\" }, req, socket, head, opts);\n    },\n    async close() {\n      killChild(\"SIGTERM\");\n    },\n  };\n}\n"
  },
  {
    "path": "src/routing.ts",
    "content": "import type { Nitro, NitroEventHandler, NitroRouteRules } from \"nitro/types\";\nimport type { RouterContext } from \"rou3\";\nimport type { RouterCompilerOptions } from \"rou3/compiler\";\n\nimport { join } from \"pathe\";\nimport { runtimeDir } from \"nitro/meta\";\nimport { addRoute, createRouter, findRoute, findAllRoutes } from \"rou3\";\nimport { compileRouterToString } from \"rou3/compiler\";\nimport { hash } from \"ohash\";\n\nconst isGlobalMiddleware = (h: NitroEventHandler) => !h.method && (!h.route || h.route === \"/**\");\n\nexport function initNitroRouting(nitro: Nitro) {\n  const envConditions = new Set(\n    [\n      nitro.options.dev ? \"dev\" : \"prod\",\n      nitro.options.preset,\n      nitro.options.preset === \"nitro-prerender\" ? \"prerender\" : undefined,\n    ].filter(Boolean) as string[]\n  );\n  const matchesEnv = (h: NitroEventHandler) => {\n    const hEnv = Array.isArray(h.env) ? h.env : [h.env];\n    const envs = hEnv.filter(Boolean) as string[];\n    return envs.length === 0 || envs.some((env) => envConditions.has(env));\n  };\n\n  type MaybeArray<T> = T | T[];\n  const routes = new Router<MaybeArray<NitroEventHandler & { _importHash: string }>>(\n    nitro.options.baseURL\n  );\n\n  const routeRules = new Router<NitroRouteRules & { _route: string }>(nitro.options.baseURL);\n\n  const globalMiddleware: (NitroEventHandler & { _importHash: string })[] = [];\n\n  const routedMiddleware = new Router<NitroEventHandler & { _importHash: string }>(\n    nitro.options.baseURL\n  );\n\n  const sync = () => {\n    // Update route rules\n    routeRules._update(\n      Object.entries(nitro.options.routeRules).map(([route, data]) => ({\n        route,\n        method: \"\",\n        data: {\n          ...data,\n          _route: route,\n        },\n      }))\n    );\n\n    // Update routes\n    const _routes = [\n      ...Object.entries(nitro.options.routes).flatMap(([route, handler]) => {\n        if (typeof handler === \"string\") {\n          handler = { handler };\n        }\n        return { ...handler, route, middleware: false };\n      }),\n      ...nitro.options.handlers,\n      ...nitro.scannedHandlers,\n    ].filter((h) => h && !h.middleware && matchesEnv(h));\n    if (nitro.options.serverEntry && nitro.options.serverEntry.handler) {\n      _routes.push({\n        route: \"/**\",\n        lazy: false,\n        format: nitro.options.serverEntry.format,\n        handler: nitro.options.serverEntry.handler,\n      });\n    }\n    if (nitro.options.renderer?.handler) {\n      _routes.push({\n        route: \"/**\",\n        lazy: true,\n        handler: nitro.options.renderer?.handler,\n      });\n    }\n    routes._update(\n      _routes.map((h) => ({\n        ...h,\n        method: h.method || \"\",\n        data: handlerWithImportHash(h),\n      })),\n      { merge: true }\n    );\n\n    // Update middleware\n    const _middleware = [...nitro.scannedHandlers, ...nitro.options.handlers].filter(\n      (h) => h && h.middleware && matchesEnv(h)\n    );\n    if (nitro.options.serveStatic) {\n      _middleware.unshift({\n        route: \"/**\",\n        middleware: true,\n        handler: join(runtimeDir, \"internal/static\"),\n      });\n    }\n    globalMiddleware.splice(\n      0,\n      globalMiddleware.length,\n      ..._middleware.filter((h) => isGlobalMiddleware(h)).map((m) => handlerWithImportHash(m))\n    );\n    routedMiddleware._update(\n      _middleware\n        .filter((h) => !isGlobalMiddleware(h))\n        .map((h) => ({\n          ...h,\n          method: h.method || \"\",\n          data: handlerWithImportHash(h),\n        }))\n    );\n  };\n\n  nitro.routing = Object.freeze({\n    sync,\n    routes,\n    routeRules,\n    globalMiddleware,\n    routedMiddleware,\n  });\n}\n\nfunction handlerWithImportHash(h: NitroEventHandler) {\n  const id = (h.lazy ? \"_lazy_\" : \"_\") + hash(h.handler).replace(/-/g, \"\").slice(0, 6);\n  return { ...h, _importHash: id };\n}\n\n// --- Router ---\n\nexport interface Route<T = unknown> {\n  route: string;\n  method: string;\n  data: T;\n}\n\nexport class Router<T> {\n  _routes?: Route<T>[];\n  _router?: RouterContext<T>;\n  _compiled?: Record<string, string>;\n  _baseURL: string;\n\n  constructor(baseURL?: string) {\n    this._update([]);\n    this._baseURL = baseURL || \"\";\n    if (this._baseURL.endsWith(\"/\")) {\n      this._baseURL = this._baseURL.slice(0, -1);\n    }\n  }\n\n  get routes() {\n    return this._routes!;\n  }\n\n  _update(routes: Route<T>[], opts?: { merge?: boolean }) {\n    this._routes = routes;\n    this._router = createRouter<T>();\n    this._compiled = undefined;\n    for (const route of routes) {\n      addRoute(this._router, route.method, this._baseURL + route.route, route.data);\n    }\n    if (opts?.merge) {\n      mergeCatchAll(this._router);\n    }\n  }\n\n  hasRoutes() {\n    return this._routes!.length > 0;\n  }\n\n  compileToString(opts?: RouterCompilerOptions<T>) {\n    const key = opts ? hash(opts) : \"\";\n    this._compiled ||= {};\n    if (this._compiled[key]) {\n      return this._compiled[key];\n    }\n    this._compiled[key] = compileRouterToString(this._router!, undefined, opts);\n\n    // TODO: Upstream to rou3 compiler\n    const onlyWildcard =\n      this.routes.length === 1 && this.routes[0].route === \"/**\" && this.routes[0].method === \"\";\n    if (onlyWildcard) {\n      // Optimize for single wildcard route\n      const data = (opts?.serialize || JSON.stringify)(this.routes[0].data);\n      let retCode = `{data,params:{\"_\":p.slice(1)}}`;\n      if (opts?.matchAll) {\n        retCode = `[${retCode}]`;\n      }\n      this._compiled[key] =\n        /* js */ `/* @__PURE__ */ (() => {const data=${data};return ((_m, p)=>{return ${retCode};})})()`;\n    }\n\n    return this._compiled[key];\n  }\n\n  match(method: string, path: string): undefined | T {\n    return findRoute(this._router!, method, path)?.data;\n  }\n\n  matchAll(method: string, path: string): T[] {\n    // Returns from less specific to more specific matches\n    return findAllRoutes(this._router!, method, path).map((route) => route.data);\n  }\n}\n\nfunction mergeCatchAll(router: RouterContext<unknown>) {\n  const handlers = router.root?.wildcard?.methods?.[\"\"];\n  if (!handlers || handlers.length < 2) {\n    return;\n  }\n  handlers.splice(0, handlers.length, {\n    ...handlers[0],\n    data: handlers.map((h) => h.data),\n  });\n}\n"
  },
  {
    "path": "src/runtime/app.ts",
    "content": "export { useNitroApp, useNitroHooks, serverFetch, getRouteRules, fetch } from \"./internal/app.ts\";\n"
  },
  {
    "path": "src/runtime/cache.ts",
    "content": "export { defineCachedFunction, defineCachedHandler } from \"./internal/cache.ts\";\n"
  },
  {
    "path": "src/runtime/config.ts",
    "content": "import type { NitroConfig } from \"nitro/types\";\n\nexport function defineConfig(config: Omit<NitroConfig, \"rootDir\">): Omit<NitroConfig, \"rootDir\"> {\n  return config;\n}\n\nexport { defineConfig as defineNitroConfig };\n"
  },
  {
    "path": "src/runtime/context.ts",
    "content": "export { useRequest } from \"./internal/context.ts\";\n"
  },
  {
    "path": "src/runtime/database.ts",
    "content": "export { useDatabase } from \"./internal/database.ts\";\n"
  },
  {
    "path": "src/runtime/internal/app.ts",
    "content": "import type {\n  CaptureError,\n  MatchedRouteRules,\n  NitroApp,\n  NitroAsyncContext,\n  NitroRuntimeHooks,\n} from \"nitro/types\";\nimport type { ServerRequest, ServerRequestContext } from \"srvx\";\nimport type { H3Config, H3EventContext, Middleware, WebSocketHooks } from \"h3\";\nimport { H3Core, toRequest } from \"h3\";\nimport { HookableCore } from \"hookable\";\nimport { nitroAsyncContext } from \"./context.ts\";\n\n// IMPORTANT: virtual imports and user code should be imported last to avoid initialization order issues\nimport errorHandler from \"#nitro/virtual/error-handler\";\nimport { plugins } from \"#nitro/virtual/plugins\";\nimport {\n  findRoute,\n  findRouteRules,\n  globalMiddleware,\n  findRoutedMiddleware,\n} from \"#nitro/virtual/routing\";\nimport {\n  hasRouteRules,\n  hasRoutedMiddleware,\n  hasGlobalMiddleware,\n  hasRoutes,\n  hasHooks,\n  hasPlugins,\n} from \"#nitro/virtual/feature-flags\";\n\ndeclare global {\n  var __nitro__:\n    | Partial<Record<\"default\" | \"prerender\" | (string & {}), NitroApp | undefined>>\n    | undefined;\n}\n\nconst APP_ID = import.meta.prerender ? \"prerender\" : \"default\";\n\nexport function useNitroApp(): NitroApp {\n  let instance: NitroApp | undefined = (useNitroApp as any)._instance;\n  if (instance) {\n    return instance;\n  }\n  instance = (useNitroApp as any)._instance = createNitroApp();\n  globalThis.__nitro__ = globalThis.__nitro__ || {};\n  globalThis.__nitro__[APP_ID] = instance;\n  if (hasPlugins) {\n    initNitroPlugins(instance);\n  }\n  return instance;\n}\n\nexport function useNitroHooks(): HookableCore<NitroRuntimeHooks> {\n  const nitroApp = useNitroApp();\n  const hooks = nitroApp.hooks;\n  if (hooks) {\n    return hooks;\n  }\n  return (nitroApp.hooks = new HookableCore<NitroRuntimeHooks>());\n}\n\nexport function serverFetch(\n  resource: string | URL | Request,\n  init?: RequestInit,\n  context?: ServerRequestContext | H3EventContext\n): Promise<Response> {\n  const req = toRequest(resource, init);\n  req.context = { ...req.context, ...context };\n  const appHandler = useNitroApp().fetch;\n  try {\n    return Promise.resolve(appHandler(req));\n  } catch (error) {\n    return Promise.reject(error);\n  }\n}\n\nexport async function resolveWebsocketHooks(req: ServerRequest): Promise<Partial<WebSocketHooks>> {\n  // https://github.com/h3js/h3/blob/c11ca743d476e583b3b47de1717e6aae92114357/src/utils/ws.ts#L37\n  const hooks = ((await serverFetch(req)) as any).crossws as Partial<WebSocketHooks>;\n  return hooks || {};\n}\n\nexport function fetch(\n  resource: string | URL | Request,\n  init?: RequestInit,\n  context?: ServerRequestContext | H3EventContext\n): Promise<Response> {\n  if (typeof resource === \"string\" && resource.charCodeAt(0) === 47) {\n    return serverFetch(resource, init, context);\n  }\n  resource = (resource as any)._request || resource; // unwrap srvx request\n  return fetch(resource, init);\n}\n\nfunction createNitroApp(): NitroApp {\n  const hooks = hasHooks ? new HookableCore<NitroRuntimeHooks>() : undefined;\n\n  const captureError: CaptureError = (error, errorCtx) => {\n    const promise =\n      hasHooks &&\n      hooks!.callHook(\"error\", error, errorCtx)?.catch?.((hookError: any) => {\n        console.error(\"Error while capturing another error\", hookError);\n      });\n    if (errorCtx?.event) {\n      const errors = errorCtx.event.req.context?.nitro?.errors;\n      if (errors) {\n        errors.push({ error, context: errorCtx });\n      }\n      if (hasHooks && promise && typeof errorCtx.event.req.waitUntil === \"function\") {\n        errorCtx.event.req.waitUntil(promise);\n      }\n    }\n  };\n\n  const h3App = createH3App({\n    onError(error, event) {\n      hasHooks && captureError(error, { event });\n      return errorHandler(error, event);\n    },\n  });\n\n  if (hasHooks) {\n    h3App.config.onRequest = (event) => {\n      return hooks!.callHook(\"request\", event)?.catch?.((error: any) => {\n        captureError(error, { event, tags: [\"request\"] });\n      });\n    };\n    h3App.config.onResponse = (res, event) => {\n      return hooks!.callHook(\"response\", res, event)?.catch?.((error: any) => {\n        captureError(error, { event, tags: [\"response\"] });\n      });\n    };\n  }\n\n  let appHandler = (req: ServerRequest): Response | Promise<Response> => {\n    req.context ||= {};\n    req.context.nitro = req.context.nitro || { errors: [] };\n    return h3App.fetch(req);\n  };\n\n  // Experimental async context support\n  if (import.meta._asyncContext) {\n    const originalHandler = appHandler;\n    appHandler = (req: ServerRequest): Promise<Response> => {\n      const asyncCtx: NitroAsyncContext = { request: req as Request };\n      return nitroAsyncContext.callAsync(asyncCtx, () => originalHandler(req));\n    };\n  }\n\n  const app: NitroApp = {\n    fetch: appHandler,\n    h3: h3App,\n    hooks,\n    captureError,\n  };\n\n  return app;\n}\n\nfunction initNitroPlugins(app: NitroApp) {\n  for (const plugin of plugins) {\n    try {\n      plugin(app as NitroApp & { hooks: NonNullable<NitroApp[\"hooks\"]> });\n    } catch (error: any) {\n      app.captureError?.(error, { tags: [\"plugin\"] });\n      throw error;\n    }\n  }\n  return app;\n}\n\nfunction createH3App(config: H3Config) {\n  // Create H3 app\n  const h3App = new H3Core(config);\n\n  // Compiled route matching\n  hasRoutes && (h3App[\"~findRoute\"] = (event) => findRoute(event.req.method, event.url.pathname));\n\n  hasGlobalMiddleware && h3App[\"~middleware\"].push(...globalMiddleware);\n\n  if (hasRouteRules || hasRoutedMiddleware) {\n    h3App[\"~getMiddleware\"] = (event, route) => {\n      const needsRouting = hasRouteRules || hasRoutedMiddleware;\n      const pathname = needsRouting ? event.url.pathname : undefined;\n      const method = needsRouting ? event.req.method : undefined;\n      const middleware: Middleware[] = [];\n      if (hasRouteRules) {\n        const routeRules = getRouteRules(method!, pathname!);\n        event.context.routeRules = routeRules?.routeRules;\n        if (routeRules?.routeRuleMiddleware.length) {\n          middleware.push(...routeRules.routeRuleMiddleware);\n        }\n      }\n      hasGlobalMiddleware && middleware.push(...h3App[\"~middleware\"]);\n      hasRoutedMiddleware &&\n        middleware.push(...findRoutedMiddleware(method!, pathname!).map((r) => r.data));\n      if (hasRoutes && route?.data?.middleware?.length) {\n        middleware.push(...route.data.middleware);\n      }\n      return middleware;\n    };\n  }\n\n  return h3App;\n}\n\nexport function getRouteRules(\n  method: string,\n  pathname: string\n): {\n  routeRules?: MatchedRouteRules;\n  routeRuleMiddleware: Middleware[];\n} {\n  const m = findRouteRules(method, pathname);\n  if (!m?.length) {\n    return { routeRuleMiddleware: [] };\n  }\n  const routeRules: MatchedRouteRules = {};\n  for (const layer of m) {\n    for (const rule of layer.data) {\n      const currentRule = routeRules[rule.name];\n      if (currentRule) {\n        if (rule.options === false) {\n          // Remove/Reset existing rule with `false` value\n          delete routeRules[rule.name];\n          continue;\n        }\n        if (typeof currentRule.options === \"object\" && typeof rule.options === \"object\") {\n          // Merge nested rule objects\n          currentRule.options = { ...currentRule.options, ...rule.options };\n        } else {\n          // Override rule if non object\n          currentRule.options = rule.options;\n        }\n        // Routing (route and params)\n        currentRule.route = rule.route;\n        currentRule.params = { ...currentRule.params, ...layer.params };\n      } else if (rule.options !== false) {\n        routeRules[rule.name] = { ...rule, params: layer.params };\n      }\n    }\n  }\n  const middleware = [];\n  for (const rule of Object.values(routeRules)) {\n    if (rule.options === false || !rule.handler) {\n      continue;\n    }\n    middleware.push(rule.handler(rule));\n  }\n  return {\n    routeRules,\n    routeRuleMiddleware: middleware,\n  };\n}\n"
  },
  {
    "path": "src/runtime/internal/cache.ts",
    "content": "import { defineHandler, handleCacheHeaders, toResponse } from \"h3\";\nimport { FastResponse } from \"srvx\";\nimport {\n  defineCachedFunction as _defineCachedFunction,\n  defineCachedHandler as _defineCachedHandler,\n  setStorage,\n} from \"ocache\";\nimport { useNitroApp } from \"./app.ts\";\nimport { useStorage } from \"./storage.ts\";\n\nimport type { EventHandler, H3Event } from \"h3\";\nimport type { CacheOptions, CachedEventHandlerOptions } from \"nitro/types\";\n\nlet _storageReady = false;\n\nfunction ensureStorage() {\n  if (_storageReady) {\n    return;\n  }\n  _storageReady = true;\n  const storage = useStorage();\n  setStorage({\n    get: (key) => storage.getItem(key) as any,\n    set: (key, value, opts) =>\n      storage.setItem(key, value as any, opts?.ttl ? { ttl: opts.ttl } : undefined),\n  });\n}\n\nfunction defaultOnError(error: unknown) {\n  console.error(\"[cache]\", error);\n  useNitroApp().captureError?.(error as Error, { tags: [\"cache\"] });\n}\n\nexport function defineCachedFunction<T, ArgsT extends unknown[] = any[]>(\n  fn: (...args: ArgsT) => T | Promise<T>,\n  opts: CacheOptions<T, ArgsT> = {}\n): (...args: ArgsT) => Promise<T> {\n  ensureStorage();\n  return _defineCachedFunction(fn, {\n    group: \"nitro/functions\",\n    onError: defaultOnError,\n    ...opts,\n  });\n}\n\nexport function defineCachedHandler(\n  handler: EventHandler,\n  opts: CachedEventHandlerOptions = {}\n): EventHandler {\n  ensureStorage();\n  const ocacheHandler = _defineCachedHandler(handler as any, {\n    group: \"nitro/handlers\",\n    onError: defaultOnError,\n    toResponse: (value, event) => toResponse(value, event as H3Event),\n    createResponse: (body, init) => new FastResponse(body, init),\n    handleCacheHeaders: (event, conditions) => handleCacheHeaders(event as H3Event, conditions),\n    ...opts,\n  });\n  return defineHandler((event) => ocacheHandler(event as any));\n}\n"
  },
  {
    "path": "src/runtime/internal/context.ts",
    "content": "import type { NitroAsyncContext } from \"nitro/types\";\nimport type { ServerRequest } from \"srvx\";\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { HTTPError } from \"h3\";\nimport { getContext, type UseContext } from \"unctx\";\n\nexport const nitroAsyncContext: UseContext<NitroAsyncContext> = /* @__PURE__ */ (() =>\n  getContext<NitroAsyncContext>(\"nitro-app\", {\n    asyncContext: import.meta._asyncContext,\n    AsyncLocalStorage: import.meta._asyncContext ? AsyncLocalStorage : undefined,\n  }))();\n\n/**\n *\n * Access to the current Nitro request.\n *\n * @experimental\n *  - Requires `experimental.asyncContext: true` config to work.\n *  - Works in Node.js and limited runtimes only\n *\n */\nexport function useRequest(): ServerRequest {\n  try {\n    return nitroAsyncContext.use().request;\n  } catch {\n    const hint = import.meta._asyncContext\n      ? \"Note: This is an experimental feature and might be broken on non-Node.js environments.\"\n      : \"Enable the experimental flag using `experimental.asyncContext: true`.\";\n    throw new HTTPError({\n      message: `Nitro request context is not available. ${hint}`,\n    });\n  }\n}\n"
  },
  {
    "path": "src/runtime/internal/database.ts",
    "content": "import type { Database } from \"db0\";\nimport { createDatabase } from \"db0\";\nimport { connectionConfigs } from \"#nitro/virtual/database\";\n\nconst instances: Record<string, Database> = Object.create(null);\n\nexport function useDatabase(name = \"default\"): Database {\n  if (instances[name]) {\n    return instances[name];\n  }\n  if (!connectionConfigs[name]) {\n    throw new Error(`Database connection \"${name}\" not configured.`);\n  }\n  return (instances[name] = createDatabase(\n    connectionConfigs[name].connector(connectionConfigs[name].options || {})\n  ));\n}\n"
  },
  {
    "path": "src/runtime/internal/empty.ts",
    "content": ""
  },
  {
    "path": "src/runtime/internal/error/dev.ts",
    "content": "import { HTTPError, type HTTPEvent } from \"h3\";\nimport { getRequestURL } from \"h3\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve, dirname } from \"node:path\";\nimport consola from \"consola\";\nimport type { ErrorParser } from \"youch-core\";\nimport { defineNitroErrorHandler } from \"./utils.ts\";\nimport type { InternalHandlerResponse } from \"./utils.ts\";\nimport { FastResponse } from \"srvx\";\nimport type { NitroErrorHandler } from \"nitro/types\";\n\nconst errorHandler: NitroErrorHandler = defineNitroErrorHandler(\n  async function defaultNitroErrorHandler(error, event) {\n    const res = await defaultHandler(error, event);\n    return new FastResponse(\n      typeof res.body === \"string\" ? res.body : JSON.stringify(res.body, null, 2),\n      res\n    );\n  }\n);\n\nexport default errorHandler;\n\nexport async function defaultHandler(\n  error: HTTPError,\n  event: HTTPEvent,\n  opts?: { silent?: boolean; json?: boolean }\n): Promise<InternalHandlerResponse> {\n  const unhandled = error.unhandled ?? !HTTPError.isError(error);\n  const { status = 500, statusText = \"\" } = unhandled ? {} : error;\n  const url = getRequestURL(event, { xForwardedHost: true, xForwardedProto: true });\n\n  // Redirects with base URL\n  if (status === 404) {\n    const baseURL = import.meta.baseURL || \"/\";\n    if (/^\\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {\n      return {\n        status: 302,\n        statusText: \"Found\",\n        headers: new Headers({ location: `${baseURL}${url.pathname.slice(1)}${url.search}` }),\n        body: `Redirecting...`,\n      };\n    }\n  }\n\n  // Load stack trace with source maps\n  await loadStackTrace(error).catch(consola.error);\n\n  const { Youch } = await import(\"youch\");\n\n  // https://github.com/poppinss/youch\n  const youch = new Youch();\n\n  // Console output\n  if (unhandled && !opts?.silent) {\n    const ansiError = (await youch.toANSI(error)).replaceAll(process.cwd(), \".\");\n    consola.error(`[request error] [${event.req.method}] ${url}\\n\\n`, ansiError);\n  }\n\n  // Use HTML response only when user-agent expects it (browsers)\n  const useJSON = opts?.json ?? !event.req.headers.get(\"accept\")?.includes(\"text/html\");\n\n  const headers = new Headers(unhandled ? {} : error.headers);\n\n  if (useJSON) {\n    headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n    const jsonBody =\n      typeof error.toJSON === \"function\"\n        ? error.toJSON()\n        : { status, statusText, message: error.message };\n    return {\n      status,\n      statusText,\n      headers,\n      body: {\n        error: true,\n        stack: error.stack?.split(\"\\n\").map((line) => line.trim()),\n        ...jsonBody,\n      },\n    };\n  }\n\n  // HTML response\n  headers.set(\"Content-Type\", \"text/html; charset=utf-8\");\n  return {\n    status,\n    statusText: unhandled ? \"\" : error.statusText,\n    headers,\n    body: await youch.toHTML(error, {\n      request: {\n        url: url.href,\n        method: event.req.method,\n        headers: Object.fromEntries(event.req.headers.entries()),\n      },\n    }),\n  };\n}\n\n// ---- Source Map support ----\n\nexport async function loadStackTrace(error: any): Promise<void> {\n  if (!(error instanceof Error)) {\n    return;\n  }\n\n  const { ErrorParser } = await import(\"youch-core\");\n\n  const parsed = await new ErrorParser().defineSourceLoader(sourceLoader).parse(error);\n\n  const stack = error.message + \"\\n\" + parsed.frames.map((frame) => fmtFrame(frame)).join(\"\\n\");\n\n  Object.defineProperty(error, \"stack\", { value: stack });\n\n  if (error.cause) {\n    await loadStackTrace(error.cause).catch(consola.error);\n  }\n}\n\ntype SourceLoader = Parameters<ErrorParser[\"defineSourceLoader\"]>[0];\ntype StackFrame = Parameters<SourceLoader>[0];\nasync function sourceLoader(frame: StackFrame) {\n  if (!frame.fileName || frame.fileType !== \"fs\" || frame.type === \"native\") {\n    return;\n  }\n\n  if (frame.type === \"app\") {\n    // prettier-ignore\n    const rawSourceMap = await readFile(`${frame.fileName}.map`, \"utf8\").catch(() => {});\n    if (rawSourceMap) {\n      const { SourceMapConsumer } = await import(\"source-map\");\n      const consumer = await new SourceMapConsumer(rawSourceMap);\n      // prettier-ignore\n      const originalPosition = consumer.originalPositionFor({ line: frame.lineNumber!, column: frame.columnNumber! });\n      if (originalPosition.source && originalPosition.line) {\n        // prettier-ignore\n        frame.fileName = resolve(dirname(frame.fileName), originalPosition.source);\n        frame.lineNumber = originalPosition.line;\n        frame.columnNumber = originalPosition.column || 0;\n      }\n    }\n  }\n\n  const contents = await readFile(frame.fileName, \"utf8\").catch(() => {});\n  return contents ? { contents } : undefined;\n}\n\nfunction fmtFrame(frame: StackFrame) {\n  if (frame.type === \"native\") {\n    return frame.raw;\n  }\n  const src = `${frame.fileName || \"\"}:${frame.lineNumber}:${frame.columnNumber})`;\n  return frame.functionName ? `at ${frame.functionName} (${src}` : `at ${src}`;\n}\n"
  },
  {
    "path": "src/runtime/internal/error/hooks.ts",
    "content": "import { useNitroApp } from \"../app.ts\";\n\nfunction _captureError(error: Error, type: string): void {\n  console.error(`[${type}]`, error);\n  useNitroApp().captureError?.(error, { tags: [type] });\n}\n\nexport function trapUnhandledErrors(): void {\n  process.on(\"unhandledRejection\", (error: Error) => _captureError(error, \"unhandledRejection\"));\n  process.on(\"uncaughtException\", (error: Error) => _captureError(error, \"uncaughtException\"));\n}\n"
  },
  {
    "path": "src/runtime/internal/error/prod.ts",
    "content": "import { HTTPError, type H3Event, type HTTPEvent } from \"h3\";\nimport type { InternalHandlerResponse } from \"./utils.ts\";\nimport { FastResponse } from \"srvx\";\nimport type { NitroErrorHandler } from \"nitro/types\";\n\nconst errorHandler: NitroErrorHandler = (error, event) => {\n  const res = defaultHandler(error, event);\n  return new FastResponse(\n    typeof res.body === \"string\" ? res.body : JSON.stringify(res.body, null, 2),\n    res\n  );\n};\n\nexport default errorHandler;\n\nexport function defaultHandler(error: HTTPError, event: HTTPEvent): InternalHandlerResponse {\n  const unhandled = error.unhandled ?? !HTTPError.isError(error);\n  const { status = 500, statusText = \"\" } = unhandled ? {} : error;\n\n  if (status === 404) {\n    const url = (event as H3Event).url || new URL(event.req.url);\n    const baseURL = import.meta.baseURL || \"/\";\n    if (/^\\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {\n      return {\n        status: 302,\n        headers: new Headers({ location: `${baseURL}${url.pathname.slice(1)}${url.search}` }),\n      };\n    }\n  }\n\n  const headers = new Headers(unhandled ? {} : error.headers);\n  headers.set(\"content-type\", \"application/json; charset=utf-8\");\n\n  const jsonBody = unhandled\n    ? { status, unhandled: true }\n    : typeof error.toJSON === \"function\"\n      ? error.toJSON()\n      : { status, statusText, message: error.message };\n\n  return {\n    status,\n    statusText,\n    headers,\n    body: {\n      error: true,\n      ...jsonBody,\n    },\n  };\n}\n"
  },
  {
    "path": "src/runtime/internal/error/utils.ts",
    "content": "import type { NitroErrorHandler } from \"nitro/types\";\n\nexport function defineNitroErrorHandler(handler: NitroErrorHandler): NitroErrorHandler {\n  return handler;\n}\n\nexport type InternalHandlerResponse = {\n  status?: number;\n  statusText?: string | undefined;\n  headers?: HeadersInit;\n  body?: string | Record<string, any>;\n};\n"
  },
  {
    "path": "src/runtime/internal/meta.ts",
    "content": "import type { NitroRouteMeta } from \"nitro/types\";\n\nexport function defineRouteMeta(meta: NitroRouteMeta): NitroRouteMeta {\n  return meta;\n}\n"
  },
  {
    "path": "src/runtime/internal/plugin.ts",
    "content": "import type { NitroAppPlugin } from \"nitro/types\";\n\nexport function defineNitroPlugin(def: NitroAppPlugin): NitroAppPlugin {\n  return def;\n}\n\nexport const nitroPlugin: (def: NitroAppPlugin) => NitroAppPlugin = defineNitroPlugin;\n"
  },
  {
    "path": "src/runtime/internal/route-rules.ts",
    "content": "import { proxyRequest, redirect as sendRedirect, requireBasicAuth } from \"h3\";\nimport type { BasicAuthOptions, EventHandler, Middleware } from \"h3\";\nimport type { MatchedRouteRule, NitroRouteRules } from \"nitro/types\";\nimport { joinURL, withQuery, withoutBase } from \"ufo\";\nimport { defineCachedHandler } from \"./cache.ts\";\n\n// Note: Remember to update RuntimeRouteRules in src/build/virtual/routing.ts when adding new route rules\n\ntype RouteRuleCtor<T extends keyof NitroRouteRules> = (m: MatchedRouteRule<T>) => Middleware;\n\n// Headers route rule\nexport const headers: RouteRuleCtor<\"headers\"> = ((m) =>\n  function headersRouteRule(event) {\n    for (const [key, value] of Object.entries(m.options || {})) {\n      event.res.headers.set(key, value);\n    }\n  }) satisfies RouteRuleCtor<\"headers\">;\n\n// Redirect route rule\nexport const redirect: RouteRuleCtor<\"redirect\"> = ((m) =>\n  function redirectRouteRule(event) {\n    let target = m.options?.to;\n    if (!target) {\n      return;\n    }\n    if (target.endsWith(\"/**\")) {\n      let targetPath = event.url.pathname + event.url.search;\n      const strpBase = (m.options as any)._redirectStripBase;\n      if (strpBase) {\n        targetPath = withoutBase(targetPath, strpBase);\n      }\n      target = joinURL(target.slice(0, -3), targetPath);\n    } else if (event.url.search) {\n      target = withQuery(target, Object.fromEntries(event.url.searchParams));\n    }\n    return sendRedirect(target, m.options?.status);\n  }) satisfies RouteRuleCtor<\"redirect\">;\n\n// Proxy route rule\nexport const proxy: RouteRuleCtor<\"proxy\"> = ((m) =>\n  function proxyRouteRule(event) {\n    let target = m.options?.to;\n    if (!target) {\n      return;\n    }\n    if (target.endsWith(\"/**\")) {\n      let targetPath = event.url.pathname + event.url.search;\n      const strpBase = (m.options as any)._proxyStripBase;\n      if (strpBase) {\n        targetPath = withoutBase(targetPath, strpBase);\n      }\n      target = joinURL(target.slice(0, -3), targetPath);\n    } else if (event.url.search) {\n      target = withQuery(target, Object.fromEntries(event.url.searchParams));\n    }\n    return proxyRequest(event, target, {\n      ...m.options,\n    });\n  }) satisfies RouteRuleCtor<\"proxy\">;\n\n// Cache route rule\nexport const cache: RouteRuleCtor<\"cache\"> = ((m) =>\n  function cacheRouteRule(event, next) {\n    if (!event.context.matchedRoute) {\n      return next();\n    }\n    const cachedHandlers: Map<string, EventHandler> = ((globalThis as any).__nitroCachedHandlers ??=\n      new Map());\n    const { handler, route } = event.context.matchedRoute;\n    const key = `${m.route}:${route}`;\n    let cachedHandler = cachedHandlers.get(key);\n    if (!cachedHandler) {\n      cachedHandler = defineCachedHandler(handler, {\n        group: \"nitro/route-rules\",\n        name: key,\n        ...m.options,\n      });\n      cachedHandlers.set(key, cachedHandler);\n    }\n    return cachedHandler(event);\n  }) satisfies RouteRuleCtor<\"cache\">;\n\n// basicAuth auth route rule\nexport const basicAuth: RouteRuleCtor<\"auth\"> = ((m) =>\n  async function authRouteRule(event, next) {\n    if (!m.options) {\n      return;\n    }\n    await requireBasicAuth(event, m.options as BasicAuthOptions);\n    return next();\n  }) satisfies RouteRuleCtor<\"auth\">;\n"
  },
  {
    "path": "src/runtime/internal/routes/dev-tasks.ts",
    "content": "import { H3 } from \"h3\";\nimport { runTask } from \"../task.ts\";\n\nimport { scheduledTasks, tasks } from \"#nitro/virtual/tasks\";\n\nconst app: H3 = new H3()\n  .get(\"/_nitro/tasks\", async () => {\n    const _tasks = await Promise.all(\n      Object.entries(tasks).map(async ([name, task]) => {\n        const _task = await task.resolve?.();\n        return [name, { description: _task?.meta?.description }];\n      })\n    );\n    return {\n      tasks: Object.fromEntries(_tasks),\n      scheduledTasks,\n    };\n  })\n  .get(\"/_nitro/tasks/:name\", async (event) => {\n    const name = event.context.params?.name;\n    const body = (await event.req.json().catch(() => ({}))) as Record<string, unknown>;\n    const payload = {\n      ...Object.fromEntries(event.url.searchParams.entries()),\n      ...body,\n    };\n    return await runTask(name!, {\n      context: { waitUntil: event.req.waitUntil },\n      payload,\n    });\n  });\n\nexport default app;\n"
  },
  {
    "path": "src/runtime/internal/routes/openapi.ts",
    "content": "import { defineHandler, getRequestURL } from \"h3\";\nimport type { EventHandler, HTTPMethod } from \"h3\";\nimport type {\n  Extensable,\n  OpenAPI3,\n  OperationObject,\n  ParameterObject,\n  PathItemObject,\n  PathsObject,\n} from \"../../../types/openapi-ts.ts\";\nimport { joinURL } from \"ufo\";\nimport { defu } from \"defu\";\nimport { handlersMeta } from \"#nitro/virtual/routing-meta\";\nimport { useRuntimeConfig } from \"../runtime-config.ts\";\n\n// Served as /_openapi.json\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n\n  const base = runtimeConfig.app?.baseURL;\n  const url = joinURL(getRequestURL(event).origin, base);\n\n  const meta = {\n    title: \"Nitro Server Routes\",\n    ...runtimeConfig.nitro?.openAPI?.meta,\n  };\n\n  const {\n    paths,\n    globals: { components, ...globalsRest },\n  } = getHandlersMeta();\n\n  const extensible: Extensable = Object.fromEntries(\n    Object.entries(globalsRest).filter(([key]) => key.startsWith(\"x-\"))\n  );\n\n  return {\n    openapi: \"3.1.0\",\n    info: {\n      title: meta?.title,\n      version: meta?.version || \"1.0.0\",\n      description: meta?.description,\n    },\n    servers: [\n      {\n        url,\n        description: \"Local Development Server\",\n        variables: {},\n      },\n    ],\n    paths,\n    components,\n    ...extensible,\n  } satisfies OpenAPI3;\n}) as EventHandler;\n\ntype OpenAPIGlobals = Pick<OpenAPI3, \"components\"> & Extensable;\n\nfunction getHandlersMeta(): {\n  paths: PathsObject;\n  globals: OpenAPIGlobals;\n} {\n  const paths: PathsObject = {};\n  let globals: OpenAPIGlobals = {};\n\n  for (const h of handlersMeta) {\n    const { route, parameters } = normalizeRoute(h.route || \"\");\n    const tags = defaultTags(h.route || \"\");\n    const method = (h.method || \"get\").toLowerCase() as Lowercase<HTTPMethod>;\n    const { $global, ...openAPI } = h.meta?.openAPI || {};\n\n    const item: PathItemObject = {\n      [method]: {\n        tags,\n        parameters,\n        responses: {\n          200: { description: \"OK\" },\n        },\n        ...openAPI,\n      } satisfies OperationObject,\n    };\n\n    if ($global) {\n      // TODO: Warn on conflicting global definitions?\n      globals = defu($global, globals);\n    }\n\n    if (paths[route] === undefined) {\n      paths[route] = item;\n    } else {\n      Object.assign(paths[route], item);\n    }\n  }\n\n  return { paths, globals };\n}\n\nfunction normalizeRoute(_route: string) {\n  const parameters: ParameterObject[] = [];\n\n  let anonymousCtr = 0;\n  const route = _route\n    .replace(/:(\\w+)/g, (_, name) => `{${name}}`)\n    .replace(/\\/(\\*)\\//g, () => `/{param${++anonymousCtr}}/`)\n    .replace(/\\*\\*{/, \"{\")\n    .replace(/\\/(\\*\\*)$/g, () => `/{*param${++anonymousCtr}}`);\n\n  const paramMatches = route.matchAll(/{(\\*?\\w+)}/g);\n  for (const match of paramMatches) {\n    const name = match[1];\n    if (!parameters.some((p) => p.name === name)) {\n      parameters.push({\n        name,\n        in: \"path\",\n        required: true,\n        schema: { type: \"string\" },\n      });\n    }\n  }\n\n  return {\n    route,\n    parameters,\n  };\n}\n\nfunction defaultTags(route: string) {\n  const tags: string[] = [];\n\n  if (route.startsWith(\"/api/\")) {\n    tags.push(\"API Routes\");\n  } else if (route.startsWith(\"/_\")) {\n    tags.push(\"Internal\");\n  } else {\n    tags.push(\"App Routes\");\n  }\n\n  return tags;\n}\n"
  },
  {
    "path": "src/runtime/internal/routes/renderer-template.dev.ts",
    "content": "import type { H3Event } from \"h3\";\nimport { serverFetch } from \"../app.ts\";\nimport {\n  rendererTemplate,\n  rendererTemplateFile,\n  isStaticTemplate,\n} from \"#nitro/virtual/renderer-template\";\nimport { HTTPResponse } from \"h3\";\nimport { hasTemplateSyntax, renderToResponse, compileTemplate } from \"rendu\";\n\nexport default async function renderIndexHTML(event: H3Event): Promise<HTTPResponse | Response> {\n  let html = await rendererTemplate(event.req as Request);\n\n  if ((globalThis as any).__transform_html__) {\n    html = await (globalThis as any).__transform_html__(html);\n  }\n\n  const isStatic = isStaticTemplate ?? !hasTemplateSyntax(html);\n  if (isStatic) {\n    return new HTTPResponse(html, {\n      headers: { \"content-type\": \"text/html; charset=utf-8\" },\n    });\n  }\n\n  const template = compileTemplate(html, { filename: rendererTemplateFile });\n  return renderToResponse(template, {\n    request: event.req as Request,\n    context: { serverFetch },\n  });\n}\n"
  },
  {
    "path": "src/runtime/internal/routes/renderer-template.ts",
    "content": "import type { H3Event } from \"h3\";\nimport { rendererTemplate } from \"#nitro/virtual/renderer-template\";\n\nexport default function renderIndexHTML(event: H3Event): any {\n  return rendererTemplate(event.req as Request);\n}\n"
  },
  {
    "path": "src/runtime/internal/routes/scalar.ts",
    "content": "import type { ApiReferenceConfiguration } from \"@scalar/api-reference\";\nimport { defineHandler, type EventHandler } from \"h3\";\nimport { useRuntimeConfig } from \"../runtime-config.ts\";\n\n// Served as /_scalar\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n  const title = runtimeConfig.nitro?.openAPI?.meta?.title || \"API Reference\";\n  const description = runtimeConfig.nitro?.openAPI?.meta?.description || \"\";\n  const openAPIEndpoint = runtimeConfig.nitro?.openAPI?.route || \"./_openapi.json\";\n\n  // https://github.com/scalar/scalar\n  const _config = runtimeConfig.nitro?.openAPI?.ui?.scalar as ApiReferenceConfiguration;\n  const scalarConfig: ApiReferenceConfiguration = {\n    ..._config,\n    url: openAPIEndpoint,\n    // @ts-expect-error\n    spec: { url: openAPIEndpoint, ..._config?.spec },\n  };\n\n  // The default page title\n\n  event.res.headers.set(\"Content-Type\", \"text/html\");\n  return /* html */ `<!doctype html>\n    <html lang=\"en\">\n      <head>\n        <meta charset=\"utf-8\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n        <meta name=\"description\" content=\"${description}\" />\n        <title>${title}</title>\n        <style>\n          ${scalarConfig.theme ? null : customTheme}\n        </style>\n      </head>\n      <body>\n        <script\n          id=\"api-reference\"\n          data-configuration=\"${JSON.stringify(scalarConfig).split('\"').join(\"&quot;\")}\"\n        ></script>\n        <script src=\"https://cdn.jsdelivr.net/npm/@scalar/api-reference\"></script>\n      </body>\n    </html>`;\n}) as EventHandler;\n\nconst customTheme = /* css */ `/* basic theme */\n  .light-mode,\n  .light-mode .dark-mode {\n    --theme-background-1: #fff;\n    --theme-background-2: #fafafa;\n    --theme-background-3: rgb(245 245 245);\n\n    --theme-color-1: #2a2f45;\n    --theme-color-2: #757575;\n    --theme-color-3: #8e8e8e;\n\n    --theme-color-accent: #ef4444;\n    --theme-background-accent: transparent;\n\n    --theme-border-color: rgba(0, 0, 0, 0.1);\n  }\n  .dark-mode {\n    --theme-background-1: #171717;\n    --theme-background-2: #262626;\n    --theme-background-3: #2e2e2e;\n\n    --theme-color-1: rgba(255, 255, 255, 0.9);\n    --theme-color-2: rgba(255, 255, 255, 0.62);\n    --theme-color-3: rgba(255, 255, 255, 0.44);\n\n    --theme-color-accent: #f87171;\n    --theme-background-accent: transparent;\n\n    --theme-border-color: rgba(255, 255, 255, 0.1);\n  }\n\n  /* Document Sidebar */\n  .light-mode .t-doc__sidebar,\n  .dark-mode .t-doc__sidebar {\n    --sidebar-background-1: var(--theme-background-1);\n    --sidebar-color-1: var(--theme-color-1);\n    --sidebar-color-2: var(--theme-color-2);\n    --sidebar-border-color: var(--theme-border-color);\n\n    --sidebar-item-hover-background: transparent;\n    --sidebar-item-hover-color: var(--sidebar-color-1);\n\n    --sidebar-item-active-background: var(--theme-background-accent);\n    --sidebar-color-active: var(--theme-color-accent);\n\n    --sidebar-search-background: transparent;\n    --sidebar-search-color: var(--theme-color-3);\n    --sidebar-search-border-color: var(--theme-border-color);\n  }\n\n  /* advanced */\n  .light-mode .dark-mode,\n  .light-mode {\n    --theme-color-green: #91b859;\n    --theme-color-red: #e53935;\n    --theme-color-yellow: #e2931d;\n    --theme-color-blue: #6182b8;\n    --theme-color-orange: #f76d47;\n    --theme-color-purple: #9c3eda;\n  }\n  .dark-mode {\n    --theme-color-green: #c3e88d;\n    --theme-color-red: #f07178;\n    --theme-color-yellow: #ffcb6b;\n    --theme-color-blue: #82aaff;\n    --theme-color-orange: #f78c6c;\n    --theme-color-purple: #c792ea;\n  }\n  /* custom-theme */\n  .section-container:nth-of-type(2)\n    ~ .section-container\n    .scalar-card\n    .scalar-card-header {\n    --theme-background-2: var(--theme-background-1) !important;\n  }\n  .section-flare {\n    width: 100%;\n    height: 100%;\n    position: absolute;\n    top: 0;\n    left: 0;\n    animation: spin 39s linear infinite;\n    transition: all 0.3s ease-in-out;\n    opacity: 1;\n  }\n  .section-flare-item:nth-of-type(1),\n  .section-flare-item:nth-of-type(2),\n  .section-flare-item:nth-of-type(3) {\n    content: \"\";\n    width: 1000px;\n    height: 1000px;\n    position: absolute;\n    top: 0;\n    right: 0;\n    border-radius: 50%;\n    background: var(--default-theme-background-1);\n    display: block;\n    opacity: 1;\n    filter: blur(48px);\n    -webkit-backface-visibility: hidden;\n    -webkit-perspective: 1000;\n    -webkit-transform: translate3d(0, 0, 0);\n    -webkit-transform: translateZ(0);\n    perspective: 1000;\n    transform: translate3d(0, 0, 0);\n    transform: translateZ(0);\n  }\n  .section-flare-item:nth-of-type(2) {\n    top: initial;\n    right: initial;\n    background: #ef4444;\n    width: 700px;\n    height: 700px;\n    opacity: 0.3;\n    animation: sectionflare 37s linear infinite;\n  }\n  .section-flare-item:nth-of-type(1) {\n    top: initial;\n    right: initial;\n    bottom: 0;\n    left: -20px;\n    background: #ef4444;\n    width: 500px;\n    height: 500px;\n    opacity: 0.3;\n    animation: sectionflare2 38s linear infinite;\n  }\n  @keyframes sectionflare {\n    0%,\n    100% {\n      transform: translate3d(0, 0, 0);\n    }\n    50% {\n      transform: translate3d(525px, 525px, 0);\n    }\n  }\n  @keyframes sectionflare2 {\n    0%,\n    100% {\n      transform: translate3d(700px, 700px, 0);\n    }\n    50% {\n      transform: translate3d(0, 0, 0);\n    }\n  }\n  @keyframes spin {\n    100% {\n      transform: rotate(360deg);\n    }\n  }\n  .section-container:nth-of-type(2) {\n    overflow: hidden;\n  }`;\n"
  },
  {
    "path": "src/runtime/internal/routes/swagger.ts",
    "content": "import { defineHandler } from \"h3\";\nimport type { EventHandler } from \"h3\";\nimport { useRuntimeConfig } from \"../runtime-config.ts\";\n\n// https://github.com/swagger-api/swagger-ui\n\nexport default defineHandler((event) => {\n  const runtimeConfig = useRuntimeConfig();\n  const title = runtimeConfig.nitro?.openAPI?.meta?.title || \"API Reference\";\n  const description = runtimeConfig.nitro?.openAPI?.meta?.description || \"\";\n  const openAPIEndpoint = runtimeConfig.nitro?.openAPI?.route || \"./_openapi.json\";\n\n  const CDN_BASE = \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@^5\";\n  event.res.headers.set(\"Content-Type\", \"text/html\");\n  return /* html */ `<!doctype html>\n    <html lang=\"en\">\n      <head>\n        <meta charset=\"utf-8\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n        <meta name=\"description\" content=\"${description}\" />\n        <title>${title}</title>\n        <link rel=\"stylesheet\" href=\"${CDN_BASE}/swagger-ui.css\" />\n      </head>\n      <body>\n        <div id=\"swagger-ui\"></div>\n        <script src=\"${CDN_BASE}/swagger-ui-bundle.js\" crossorigin></script>\n        <script\n          src=\"${CDN_BASE}/swagger-ui-standalone-preset.js\"\n          crossorigin\n        ></script>\n        <script>\n          window.onload = () => {\n            window.ui = SwaggerUIBundle({\n              url: ${JSON.stringify(openAPIEndpoint)},\n              dom_id: \"#swagger-ui\",\n              presets: [\n                SwaggerUIBundle.presets.apis,\n                SwaggerUIStandalonePreset,\n              ],\n              layout2: \"StandaloneLayout\",\n            });\n          };\n        </script>\n      </body>\n    </html> `;\n}) as EventHandler;\n"
  },
  {
    "path": "src/runtime/internal/runtime-config.ts",
    "content": "import type { NitroRuntimeConfig } from \"nitro/types\";\nimport { snakeCase } from \"scule\";\nimport { runtimeConfig } from \"#nitro/virtual/runtime-config\";\n\nexport function useRuntimeConfig(): NitroRuntimeConfig {\n  return ((useRuntimeConfig as any)._cached ||= getRuntimeConfig());\n}\n\nfunction getRuntimeConfig() {\n  const env = globalThis.process?.env || {};\n  applyEnv(runtimeConfig, {\n    prefix: \"NITRO_\",\n    altPrefix: runtimeConfig.nitro?.envPrefix ?? env?.NITRO_ENV_PREFIX ?? \"_\",\n    envExpansion: Boolean(runtimeConfig.nitro?.envExpansion ?? env?.NITRO_ENV_EXPANSION ?? false),\n  });\n  return runtimeConfig;\n}\n\n// ---- utils ----\n\ntype EnvOptions = {\n  prefix?: string;\n  altPrefix?: string;\n  envExpansion?: boolean;\n};\n\nexport function applyEnv(\n  obj: Record<string, any>,\n  opts: EnvOptions,\n  parentKey = \"\"\n): Record<string, any> {\n  for (const key in obj) {\n    const subKey = parentKey ? `${parentKey}_${key}` : key;\n    const envValue = getEnv(subKey, opts);\n    if (_isObject(obj[key])) {\n      // Same as before\n      if (_isObject(envValue)) {\n        obj[key] = { ...(obj[key] as any), ...(envValue as any) };\n        applyEnv(obj[key], opts, subKey);\n      }\n      // If envValue is undefined\n      // Then proceed to nested properties\n      else if (envValue === undefined) {\n        applyEnv(obj[key], opts, subKey);\n      }\n      // If envValue is a primitive other than undefined\n      // Then set objValue and ignore the nested properties\n      else {\n        obj[key] = envValue ?? obj[key];\n      }\n    } else {\n      obj[key] = envValue ?? obj[key];\n    }\n    // Experimental env expansion\n    if (opts.envExpansion && typeof obj[key] === \"string\") {\n      obj[key] = _expandFromEnv(obj[key]);\n    }\n  }\n  return obj;\n}\n\nconst envExpandRx = /\\{\\{([^{}]*)\\}\\}/g;\n\nfunction _expandFromEnv(value: string) {\n  return value.replace(envExpandRx, (match, key) => {\n    return process.env[key] || match;\n  });\n}\n\nfunction getEnv(key: string, opts: EnvOptions) {\n  const envKey = snakeCase(key).toUpperCase();\n  return process.env[opts.prefix + envKey] ?? process.env[opts.altPrefix + envKey];\n}\n\nfunction _isObject(input: unknown) {\n  return input !== null && typeof input === \"object\" && !Array.isArray(input);\n}\n"
  },
  {
    "path": "src/runtime/internal/static.ts",
    "content": "import { HTTPError, defineHandler } from \"h3\";\nimport type { EventHandler, HTTPMethod } from \"h3\";\nimport type { PublicAsset } from \"nitro/types\";\nimport { decodePath, joinURL, withLeadingSlash, withoutTrailingSlash } from \"ufo\";\nimport { getAsset, isPublicAssetURL, readAsset } from \"#nitro/virtual/public-assets\";\n\nconst METHODS = new Set([\"HEAD\", \"GET\"] as HTTPMethod[]);\n\nconst EncodingMap = { gzip: \".gz\", br: \".br\", zstd: \".zst\" } as const;\n\nexport default defineHandler((event) => {\n  if (event.req.method && !METHODS.has(event.req.method as HTTPMethod)) {\n    return;\n  }\n\n  let id = decodePath(withLeadingSlash(withoutTrailingSlash(event.url.pathname)));\n\n  let asset: PublicAsset | undefined;\n\n  const encodingHeader = event.req.headers.get(\"accept-encoding\") || \"\";\n  const encodings = [\n    ...encodingHeader\n      .split(\",\")\n      .map((e) => EncodingMap[e.trim() as keyof typeof EncodingMap])\n      .filter(Boolean)\n      .sort(),\n    \"\",\n  ];\n\n  for (const encoding of encodings) {\n    for (const _id of [id + encoding, joinURL(id, \"index.html\" + encoding)]) {\n      const _asset = getAsset(_id);\n      if (_asset) {\n        asset = _asset;\n        id = _id;\n        break;\n      }\n    }\n  }\n\n  if (!asset) {\n    if (isPublicAssetURL(id)) {\n      event.res.headers.delete(\"Cache-Control\");\n      throw new HTTPError({ status: 404 });\n    }\n    return;\n  }\n\n  if (encodings.length > 1) {\n    event.res.headers.append(\"Vary\", \"Accept-Encoding\");\n  }\n\n  const ifNotMatch = event.req.headers.get(\"if-none-match\") === asset.etag;\n  if (ifNotMatch) {\n    event.res.status = 304;\n    event.res.statusText = \"Not Modified\";\n    return \"\";\n  }\n\n  const ifModifiedSinceH = event.req.headers.get(\"if-modified-since\");\n  const mtimeDate = new Date(asset.mtime);\n  if (ifModifiedSinceH && asset.mtime && new Date(ifModifiedSinceH) >= mtimeDate) {\n    event.res.status = 304;\n    event.res.statusText = \"Not Modified\";\n    return \"\";\n  }\n\n  if (asset.type) {\n    event.res.headers.set(\"Content-Type\", asset.type);\n  }\n\n  if (asset.etag && !event.res.headers.has(\"ETag\")) {\n    event.res.headers.set(\"ETag\", asset.etag);\n  }\n\n  if (asset.mtime && !event.res.headers.has(\"Last-Modified\")) {\n    event.res.headers.set(\"Last-Modified\", mtimeDate.toUTCString());\n  }\n\n  if (asset.encoding && !event.res.headers.has(\"Content-Encoding\")) {\n    event.res.headers.set(\"Content-Encoding\", asset.encoding);\n  }\n\n  if (asset.size > 0 && !event.res.headers.has(\"Content-Length\")) {\n    event.res.headers.set(\"Content-Length\", asset.size.toString());\n  }\n\n  return readAsset(id);\n}) as EventHandler;\n"
  },
  {
    "path": "src/runtime/internal/storage.ts",
    "content": "import type { Storage, StorageValue } from \"unstorage\";\nimport { prefixStorage } from \"unstorage\";\nimport { initStorage } from \"#nitro/virtual/storage\";\n\nexport function useStorage<T extends StorageValue = StorageValue>(base = \"\"): Storage<T> {\n  const storage = ((useStorage as any)._storage ??= initStorage());\n  return (base ? prefixStorage(storage, base) : storage) as unknown as Storage<T>;\n}\n"
  },
  {
    "path": "src/runtime/internal/task.ts",
    "content": "import { Cron } from \"croner\";\nimport { HTTPError } from \"h3\";\nimport type { Task, TaskContext, TaskEvent, TaskPayload, TaskResult } from \"nitro/types\";\nimport { scheduledTasks, tasks } from \"#nitro/virtual/tasks\";\n\n/** @experimental */\nexport function defineTask<RT = unknown>(def: Task<RT>): Task<RT> {\n  if (typeof def.run !== \"function\") {\n    def.run = () => {\n      throw new TypeError(\"Task must implement a `run` method!\");\n    };\n  }\n  return def;\n}\n\nconst __runningTasks__: { [name: string]: ReturnType<Task<any>[\"run\"]> } = {};\n\n/** @experimental */\nexport async function runTask<RT = unknown>(\n  name: string,\n  { payload = {}, context = {} }: { payload?: TaskPayload; context?: TaskContext } = {}\n): Promise<TaskResult<RT>> {\n  if (__runningTasks__[name]) {\n    return __runningTasks__[name];\n  }\n\n  if (!(name in tasks)) {\n    throw new HTTPError({\n      message: `Task \\`${name}\\` is not available!`,\n      status: 404,\n    });\n  }\n\n  if (!tasks[name].resolve) {\n    throw new HTTPError({\n      message: `Task \\`${name}\\` is not implemented!`,\n      status: 501,\n    });\n  }\n\n  const handler = (await tasks[name].resolve!()) as Task<RT>;\n  const taskEvent: TaskEvent = { name, payload, context };\n  __runningTasks__[name] = handler.run(taskEvent);\n\n  try {\n    const res = await __runningTasks__[name];\n    return res;\n  } finally {\n    delete __runningTasks__[name];\n  }\n}\n\n/** @experimental */\nexport function startScheduleRunner({\n  waitUntil,\n}: {\n  waitUntil?: ((promise: Promise<unknown>) => void) | undefined;\n} = {}): void {\n  if (!scheduledTasks || scheduledTasks.length === 0 || process.env.TEST) {\n    return;\n  }\n\n  const payload: TaskPayload = {\n    scheduledTime: Date.now(),\n  };\n\n  for (const schedule of scheduledTasks) {\n    new Cron(schedule.cron, async () => {\n      await Promise.all(\n        schedule.tasks.map((name) =>\n          runTask(name, {\n            payload,\n            context: { waitUntil },\n          }).catch((error) => {\n            console.error(`Error while running scheduled task \"${name}\"`, error);\n          })\n        )\n      );\n    });\n  }\n}\n\n/** @experimental */\nexport function getCronTasks(cron: string): string[] {\n  return (scheduledTasks || []).find((task) => task.cron === cron)?.tasks || [];\n}\n\n/** @experimental */\nexport function runCronTasks(\n  cron: string,\n  ctx: { payload?: TaskPayload; context?: TaskContext }\n): Promise<TaskResult[]> {\n  return Promise.all(getCronTasks(cron).map((name) => runTask(name, ctx)));\n}\n"
  },
  {
    "path": "src/runtime/internal/vite/dev-entry.mjs",
    "content": "import \"#nitro/virtual/polyfills\";\nimport wsAdapter from \"crossws/adapters/node\";\n\nimport { useNitroApp } from \"nitro/app\";\nimport { resolveWebsocketHooks } from \"#nitro/runtime/app\";\nimport { startScheduleRunner } from \"#nitro/runtime/task\";\n\nconst nitroApp = useNitroApp();\n\nexport const fetch = nitroApp.fetch;\n\nconst ws = import.meta._websocket ? wsAdapter({ resolve: resolveWebsocketHooks }) : undefined;\n\nif (import.meta._tasks) {\n  startScheduleRunner({});\n}\n\nexport const handleUpgrade = ws?.handleUpgrade;\n"
  },
  {
    "path": "src/runtime/internal/vite/dev-worker.mjs",
    "content": "import { ModuleRunner, ESModulesEvaluator } from \"vite/module-runner\";\nimport { createViteTransport } from \"env-runner/vite\";\n\n// Custom evaluator for workerd where `new AsyncFunction()` is disallowed.\n// Uses the unsafeEvalBinding exposed by the env-runner miniflare wrapper.\nclass WorkerdModuleEvaluator {\n  startOffset = 0;\n\n  async runInlinedModule(context, code) {\n    const unsafeEval = globalThis.__ENV_RUNNER_UNSAFE_EVAL__;\n    const keys = Object.keys(context);\n    const fn = unsafeEval.newAsyncFunction('\"use strict\";' + code, \"runInlinedModule\", ...keys);\n    await fn(...keys.map((k) => context[k]));\n    Object.seal(context[Object.keys(context)[0]]);\n  }\n\n  runExternalModule(filepath) {\n    return import(filepath);\n  }\n}\n\n// ----- IPC -----\n\nlet sendMessage;\nconst messageListeners = new Set();\n\n// ----- Environment runners -----\n\nconst envs = (globalThis.__nitro_vite_envs__ ??= {\n  nitro: undefined,\n  ssr: undefined,\n});\n\nclass ViteEnvRunner {\n  constructor({ name, entry }) {\n    this.name = name;\n    this.entryPath = entry;\n\n    this.entry = undefined;\n    this.entryError = undefined;\n\n    // Create Vite Module Runner\n    // https://vite.dev/guide/api-environment-runtimes.html#modulerunner\n    const onMessage = (listener) => messageListeners.add(listener);\n    const transport = createViteTransport((data) => sendMessage?.(data), onMessage, name);\n    const evaluator = globalThis.__ENV_RUNNER_UNSAFE_EVAL__\n      ? new WorkerdModuleEvaluator()\n      : new ESModulesEvaluator();\n    const debug =\n      typeof process !== \"undefined\" && process.env?.NITRO_DEBUG ? console.debug : undefined;\n    this.runner = new ModuleRunner({ transport }, evaluator, debug);\n\n    this.reload();\n  }\n\n  async reload() {\n    try {\n      this.entry = await this.runner.import(this.entryPath);\n      this.entryError = undefined;\n    } catch (error) {\n      console.error(error);\n      this.entryError = error;\n    }\n  }\n\n  async fetch(req, init) {\n    if (this.entryError) {\n      return renderError(req, this.entryError);\n    }\n    for (let i = 0; i < 5 && !(this.entry || this.entryError); i++) {\n      await new Promise((r) => setTimeout(r, 100 * Math.pow(2, i)));\n    }\n    if (this.entryError) {\n      return renderError(req, this.entryError);\n    }\n    if (!this.entry) {\n      throw httpError(503, `Vite environment \"${this.name}\" is unavailable`);\n    }\n    try {\n      const entryFetch = this.entry.fetch || this.entry.default?.fetch;\n      if (!entryFetch) {\n        throw httpError(500, `No fetch handler exported from ${this.entryPath}`);\n      }\n      return await entryFetch(req, init);\n    } catch (error) {\n      return renderError(req, error);\n    }\n  }\n}\n\n// ----- RPC -----\n\nconst rpcRequests = new Map();\n\nfunction rpc(name, data, timeout = 3000) {\n  const id = Math.random().toString(36).slice(2);\n  return new Promise((resolve, reject) => {\n    const timer = setTimeout(() => {\n      rpcRequests.delete(id);\n      reject(new Error(`RPC \"${name}\" timed out`));\n    }, timeout);\n    rpcRequests.set(id, { resolve, reject, timer });\n    sendMessage?.({ __rpc: name, __rpc_id: id, data });\n  });\n}\n\n// Trap unhandled errors to avoid worker crash\nif (typeof process !== \"undefined\" && typeof process.on === \"function\") {\n  process.on(\"unhandledRejection\", (error) => console.error(error));\n  process.on(\"uncaughtException\", (error) => console.error(error));\n}\n\n// ----- RSC Support -----\n\n// define __VITE_ENVIRONMENT_RUNNER_IMPORT__ for RSC support\n// https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-rsc/README.md#__vite_environment_runner_import__\n\nglobalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__ = async function (environmentName, id) {\n  const env = envs[environmentName];\n  if (!env) {\n    throw new Error(`Vite environment \"${environmentName}\" is not registered`);\n  }\n  return env.runner.import(id);\n};\n\n// ----- Reload -----\n\nasync function reload() {\n  try {\n    await Promise.all(Object.values(envs).map((env) => env?.reload()));\n  } catch (error) {\n    console.error(error);\n  }\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nreload();\n\n// ----- HTML Transform -----\n\nglobalThis.__transform_html__ = async function (html) {\n  html = await rpc(\"transformHTML\", html).catch((error) => {\n    console.warn(\"Failed to transform HTML via Vite:\", error);\n    return html;\n  });\n  return html;\n};\n\n// ----- Exports (env-runner AppEntry) -----\n\nexport function fetch(req) {\n  const viteEnv = req?.headers.get(\"x-vite-env\") || \"nitro\";\n  const env = envs[viteEnv];\n  if (!env) {\n    return renderError(req, httpError(500, `Unknown vite environment \"${viteEnv}\"`));\n  }\n  return env.fetch(req);\n}\n\nexport function upgrade(context) {\n  const handleUpgrade = envs.nitro?.entry?.handleUpgrade;\n  if (handleUpgrade) {\n    handleUpgrade(context.node.req, context.node.socket, context.node.head);\n  }\n}\n\nexport const ipc = {\n  onOpen(ctx) {\n    sendMessage = ctx.sendMessage;\n  },\n  onMessage(message) {\n    if (message?.__rpc_id) {\n      const req = rpcRequests.get(message.__rpc_id);\n      if (req) {\n        clearTimeout(req.timer);\n        rpcRequests.delete(message.__rpc_id);\n        if (message.error) {\n          req.reject(typeof message.error === \"string\" ? new Error(message.error) : message.error);\n        } else {\n          req.resolve(message.data);\n        }\n      }\n      return;\n    }\n    if (message?.type === \"custom\") {\n      if (message.event === \"nitro:vite-env\") {\n        const { name, entry } = message.data;\n        if (!envs[name]) {\n          envs[name] = new ViteEnvRunner({ name, entry });\n        }\n        return;\n      }\n    }\n    if (message?.type === \"full-reload\") {\n      reload();\n      return;\n    }\n    for (const listener of messageListeners) {\n      listener(message);\n    }\n  },\n  onClose() {},\n};\n\n// ----- Error handling -----\n\nfunction httpError(status, message) {\n  const error = new Error(message || `HTTP Error ${status}`);\n  error.status = status;\n  error.name = \"NitroViteError\";\n  return error;\n}\n\nasync function renderError(req, error) {\n  if (req.headers.get(\"accept\")?.includes(\"application/json\")) {\n    return new Response(\n      JSON.stringify(\n        {\n          status: error.status || 500,\n          name: error.name || \"Error\",\n          message: error.message,\n          stack: (error.stack || \"\")\n            .split(\"\\n\")\n            .splice(1)\n            .map((l) => l.trim()),\n        },\n        null,\n        2\n      ),\n      {\n        status: error.status || 500,\n        headers: {\n          \"Content-Type\": \"application/json\",\n          \"Cache-Control\": \"no-store, max-age=0, must-revalidate\",\n          Pragma: \"no-cache\",\n          Expires: \"0\",\n        },\n      }\n    );\n  }\n  try {\n    const { Youch } = await import(\"youch\");\n    const youch = new Youch();\n    return new Response(await youch.toHTML(error), {\n      status: error.status || 500,\n      headers: {\n        \"Content-Type\": \"text/html\",\n        \"Cache-Control\": \"no-store, max-age=0, must-revalidate\",\n        Pragma: \"no-cache\",\n        Expires: \"0\",\n      },\n    });\n  } catch {\n    return new Response(`<pre>${error.stack || error.message || error}</pre>`, {\n      status: error.status || 500,\n      headers: {\n        \"Content-Type\": \"text/html\",\n        \"Cache-Control\": \"no-store, max-age=0, must-revalidate\",\n        Pragma: \"no-cache\",\n        Expires: \"0\",\n      },\n    });\n  }\n}\n"
  },
  {
    "path": "src/runtime/internal/vite/ssr-renderer.mjs",
    "content": "import { fetchViteEnv } from \"nitro/vite/runtime\";\n\n/** @param {{ req: Request }} HTTPEvent */\nexport default function ssrRenderer({ req }) {\n  return fetchViteEnv(\"ssr\", req);\n}\n"
  },
  {
    "path": "src/runtime/meta.ts",
    "content": "import { fileURLToPath } from \"node:url\";\n\nimport packageJson from \"../../package.json\" with { type: \"json\" };\n\nexport const version: string = packageJson.version;\n\nconst resolve = (path: string) => fileURLToPath(new URL(path, import.meta.url));\n\nexport const runtimeDir: string = /* @__PURE__ */ resolve(\"./\");\nexport const presetsDir: string = /* @__PURE__ */ resolve(\"../presets/\");\nexport const pkgDir: string = /* @__PURE__ */ resolve(\"../../\");\n\nexport const runtimeDependencies: string[] = [\n  \"crossws\", // dep\n  \"croner\", // traced\n  \"db0\", // dep\n  \"defu\", // traced\n  \"destr\", // traced\n  \"h3\", // dep\n  \"rou3\", // sub-dep of h3\n  \"hookable\", // traced\n  \"ofetch\", // dep\n  \"ocache\", // dep\n  \"ohash\", // traced\n  \"rendu\", // traced\n  \"scule\", // traced\n  \"srvx\", // dep\n  \"ufo\", // traced\n  \"unctx\", // traced\n  \"unenv\", // dep\n  \"unstorage\", // dep\n];\n"
  },
  {
    "path": "src/runtime/nitro.ts",
    "content": "// Config\nimport type { NitroConfig } from \"nitro/types\";\nimport type { ServerRequestContext } from \"srvx\";\nimport { toRequest, type H3EventContext } from \"h3\";\n\nexport function defineConfig(config: Omit<NitroConfig, \"rootDir\">): Omit<NitroConfig, \"rootDir\"> {\n  return config;\n}\n\n// Type (only) helpers\nexport { defineNitroPlugin as definePlugin } from \"./internal/plugin.ts\";\nexport { defineRouteMeta } from \"./internal/meta.ts\";\nexport { defineNitroErrorHandler as defineErrorHandler } from \"./internal/error/utils.ts\";\n\n// H3\nexport {\n  defineHandler,\n  defineMiddleware,\n  defineWebSocketHandler,\n  html,\n  HTTPError,\n  HTTPResponse,\n} from \"h3\";\nexport type { H3Event } from \"h3\";\n\n// Runtime\nexport function serverFetch(\n  resource: string | URL | Request,\n  init?: RequestInit,\n  context?: ServerRequestContext | H3EventContext\n): Promise<Response> {\n  const nitro =\n    globalThis.__nitro__?.default ||\n    globalThis.__nitro__?.prerender ||\n    globalThis.__nitro_builder__;\n  if (!nitro) {\n    return Promise.reject(new Error(\"Nitro instance is not available.\"));\n  }\n  const req = toRequest(resource, init);\n  req.context = { ...req.context, ...context };\n  try {\n    return Promise.resolve(nitro.fetch(req));\n  } catch (error) {\n    return Promise.reject(error);\n  }\n}\n\nexport function fetch(\n  resource: string | URL | Request,\n  init?: RequestInit,\n  context?: ServerRequestContext | H3EventContext\n): Promise<Response> {\n  if (typeof resource === \"string\" && resource.charCodeAt(0) === 47) {\n    return serverFetch(resource, init, context);\n  }\n  resource = (resource as any)._request || resource; // unwrap srvx request\n  return globalThis.fetch(resource, init);\n}\n"
  },
  {
    "path": "src/runtime/runtime-config.ts",
    "content": "export { useRuntimeConfig } from \"./internal/runtime-config.ts\";\n"
  },
  {
    "path": "src/runtime/storage.ts",
    "content": "export { useStorage } from \"./internal/storage.ts\";\n"
  },
  {
    "path": "src/runtime/task.ts",
    "content": "export { defineTask, runTask } from \"./internal/task.ts\";\n"
  },
  {
    "path": "src/runtime/virtual/_runtime_warn.ts",
    "content": "import consola from \"consola\";\nimport { isTest } from \"std-env\";\n\nif (!isTest) {\n  consola.warn(\n    \"Nitro runtime imports detected without a builder or Nitro plugin. A stub implementation will be used.\"\n  );\n}\n"
  },
  {
    "path": "src/runtime/virtual/database.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport type { Connector } from \"db0\";\n\nexport const connectionConfigs: {\n  [name: string]: {\n    connector: (options: any) => Connector;\n    options: any;\n  };\n} = {};\n"
  },
  {
    "path": "src/runtime/virtual/error-handler.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport { H3Event, toResponse } from \"h3\";\nimport type { NitroErrorHandler } from \"nitro/types\";\n\ntype EParams = Parameters<NitroErrorHandler>;\ntype EReturn = ReturnType<NitroErrorHandler>;\n\nconst errorHandler: (error: EParams[0], event: EParams[1]) => EReturn = (error, event) => {\n  if (error.status !== 404) {\n    console.error(error as any);\n  }\n  return toResponse(error, event as H3Event);\n};\n\nexport default errorHandler;\n"
  },
  {
    "path": "src/runtime/virtual/feature-flags.ts",
    "content": "import \"./_runtime_warn.ts\";\n\nexport const hasRoutes: boolean = true;\nexport const hasRouteRules: boolean = true;\nexport const hasGlobalMiddleware: boolean = true;\nexport const hasRoutedMiddleware: boolean = true;\nexport const hasPlugins: boolean = true;\nexport const hasHooks: boolean = true;\n"
  },
  {
    "path": "src/runtime/virtual/plugins.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport type { NitroAppPlugin } from \"nitro/types\";\n\nexport const plugins: NitroAppPlugin[] = [];\n"
  },
  {
    "path": "src/runtime/virtual/polyfills.ts",
    "content": "import \"./_runtime_warn.ts\";\n\nexport default {};\n"
  },
  {
    "path": "src/runtime/virtual/public-assets.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport type { PublicAsset } from \"nitro/types\";\n\nexport const publicAssetBases: string[] = [];\n\nexport const isPublicAssetURL: (id: string) => boolean = () => false;\n\nexport const getPublicAssetMeta: (id: string) => { maxAge?: number } | null = () => null;\n\nexport const readAsset: (id: string) => Promise<Buffer> = async () => {\n  throw new Error(\"Asset not found\");\n};\n\nexport const getAsset: (id: string) => PublicAsset | null = () => null;\n"
  },
  {
    "path": "src/runtime/virtual/renderer-template.ts",
    "content": "import \"./_runtime_warn.ts\";\n\nexport function rendererTemplate(_req: Request): string | Promise<string> {\n  return `<!-- Renderer template not available -->`;\n}\n\n// dev only\nexport const rendererTemplateFile: string | undefined = undefined;\nexport const isStaticTemplate: boolean | undefined = undefined;\n"
  },
  {
    "path": "src/runtime/virtual/routing-meta.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport type { NitroRouteMeta } from \"nitro/types\";\n\nexport const handlersMeta: {\n  route?: string;\n  method?: string;\n  meta?: NitroRouteMeta;\n}[] = [];\n"
  },
  {
    "path": "src/runtime/virtual/routing.ts",
    "content": "import \"./_runtime_warn.ts\";\n\nimport type { Middleware, H3Route } from \"h3\";\nimport type { MatchedRoute } from \"rou3\";\nimport type { MatchedRouteRule } from \"nitro/types\";\n\nexport function findRoute(_method: string, _path: string): MatchedRoute<H3Route> | undefined {\n  return undefined;\n}\n\nexport function findRouteRules(_method: string, _path: string): MatchedRoute<MatchedRouteRule[]>[] {\n  return [];\n}\n\nexport const globalMiddleware: Middleware[] = [];\n\nexport function findRoutedMiddleware(_method: string, _path: string): MatchedRoute<Middleware>[] {\n  return [];\n}\n"
  },
  {
    "path": "src/runtime/virtual/runtime-config.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport type { NitroRuntimeConfig } from \"nitro/types\";\n\nexport const runtimeConfig: NitroRuntimeConfig = {\n  app: {},\n  nitro: {},\n};\n"
  },
  {
    "path": "src/runtime/virtual/server-assets.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport { createStorage, type Storage } from \"unstorage\";\n\nimport type { AssetMeta } from \"nitro/types\";\n\nexport const assets: Storage = createStorage();\n\nexport function readAsset<T = any>(_id: string): Promise<T> {\n  return Promise.resolve({} as T);\n}\n\nexport function statAsset(_id: string): Promise<AssetMeta> {\n  return Promise.resolve({});\n}\n\nexport function getKeys(): Promise<string[]> {\n  return Promise.resolve([]);\n}\n"
  },
  {
    "path": "src/runtime/virtual/storage.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport { type Storage, createStorage } from \"unstorage\";\n\nexport function initStorage(): Storage {\n  return createStorage();\n}\n"
  },
  {
    "path": "src/runtime/virtual/tasks.ts",
    "content": "import \"./_runtime_warn.ts\";\nimport type { Task, TaskMeta } from \"nitro/types\";\n\nexport const tasks: Record<string, { resolve?: () => Promise<Task>; meta: TaskMeta }> = {};\n\nexport const scheduledTasks: false | { cron: string; tasks: string[] }[] = [];\n"
  },
  {
    "path": "src/runtime/vite.ts",
    "content": "import { HTTPError, toRequest } from \"h3\";\n\ntype FetchableEnv = {\n  fetch: (request: Request) => Response | Promise<Response>;\n};\n\ndeclare global {\n  var __nitro_vite_envs__: Record<string, FetchableEnv>;\n}\n\nexport function fetchViteEnv(\n  viteEnvName: string,\n  input: RequestInfo | URL,\n  init?: RequestInit\n): Promise<Response> {\n  const envs = globalThis.__nitro_vite_envs__ || {};\n  const viteEnv = envs[viteEnvName as keyof typeof envs] as FetchableEnv;\n  if (!viteEnv) {\n    throw HTTPError.status(404);\n  }\n  return Promise.resolve(viteEnv.fetch(toRequest(input, init)));\n}\n"
  },
  {
    "path": "src/scan.ts",
    "content": "import { glob } from \"tinyglobby\";\nimport type { Nitro } from \"nitro/types\";\nimport { join, relative } from \"pathe\";\nimport { withBase, withLeadingSlash, withoutTrailingSlash } from \"ufo\";\n\nexport const GLOB_SCAN_PATTERN = \"**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}\";\ntype FileInfo = { path: string; fullPath: string };\n\nconst suffixRegex =\n  /(\\.(?<method>connect|delete|get|head|options|patch|post|put|trace))?(\\.(?<env>dev|prod|prerender))?$/;\n\n// prettier-ignore\ntype MatchedMethodSuffix = \"connect\" | \"delete\" | \"get\" | \"head\" | \"options\" | \"patch\" | \"post\" | \"put\" | \"trace\";\ntype MatchedEnvSuffix = \"dev\" | \"prod\" | \"prerender\";\n\nexport async function scanAndSyncOptions(nitro: Nitro) {\n  // Scan plugins\n  const scannedPlugins = await scanPlugins(nitro);\n  for (const plugin of scannedPlugins) {\n    if (!nitro.options.plugins.includes(plugin)) {\n      nitro.options.plugins.push(plugin);\n    }\n  }\n\n  // Scan tasks\n  if (nitro.options.experimental.tasks) {\n    const scannedTasks = await scanTasks(nitro);\n    for (const scannedTask of scannedTasks) {\n      if (scannedTask.name in nitro.options.tasks) {\n        if (!nitro.options.tasks[scannedTask.name].handler) {\n          nitro.options.tasks[scannedTask.name].handler = scannedTask.handler;\n        }\n      } else {\n        nitro.options.tasks[scannedTask.name] = {\n          handler: scannedTask.handler,\n          description: \"\",\n        };\n      }\n    }\n  }\n\n  // Scan modules\n  const scannedModules = await scanModules(nitro);\n  nitro.options.modules = nitro.options.modules || [];\n  for (const modPath of scannedModules) {\n    if (!nitro.options.modules.includes(modPath)) {\n      nitro.options.modules.push(modPath);\n    }\n  }\n}\n\nexport async function scanHandlers(nitro: Nitro) {\n  const middleware = await scanMiddleware(nitro);\n\n  const handlers = await Promise.all([\n    scanServerRoutes(nitro, nitro.options.apiDir || \"api\", nitro.options.apiBaseURL || \"/api\"),\n    scanServerRoutes(nitro, nitro.options.routesDir || \"routes\"),\n  ]).then((r) => r.flat());\n\n  const seenHandlers = new Set<string>();\n  nitro.scannedHandlers = [\n    ...middleware,\n    ...handlers.filter((h) => {\n      const key = `${h.route}\\0${h.method}\\0${h.env}`;\n      return seenHandlers.has(key) ? false : (seenHandlers.add(key), true);\n    }),\n  ];\n\n  nitro.routing.sync();\n\n  return handlers;\n}\n\nexport async function scanMiddleware(nitro: Nitro) {\n  const files = await scanFiles(nitro, \"middleware\");\n  return files.map((file) => {\n    return {\n      route: \"/**\",\n      middleware: true,\n      handler: file.fullPath,\n    };\n  });\n}\n\nexport async function scanServerRoutes(nitro: Nitro, dir: string, prefix = \"/\") {\n  const files = await scanFiles(nitro, dir);\n  return files.map((file) => {\n    let route = file.path\n      .replace(/\\.[A-Za-z]+$/, \"\")\n      .replace(/\\(([^(/\\\\]+)\\)[/\\\\]/g, \"\")\n      .replace(/\\[\\.{3}]/g, \"**\")\n      .replace(/\\[\\.{3}([^\\]]+)]/g, (_, p) => \"**:\" + p.replace(/[^\\w-]/g, \"_\"))\n      .replace(/\\[([^/\\]]+)]/g, (_, p) => \":\" + p.replace(/[^\\w-]/g, \"_\"));\n    route = withLeadingSlash(withoutTrailingSlash(withBase(route, prefix)));\n\n    const suffixMatch = route.match(suffixRegex);\n    let method: MatchedMethodSuffix | undefined;\n    let env: MatchedEnvSuffix | undefined;\n    if (suffixMatch?.index && suffixMatch?.index >= 0) {\n      route = route.slice(0, suffixMatch.index);\n      method = suffixMatch.groups?.method as MatchedMethodSuffix | undefined;\n      env = suffixMatch.groups?.env as MatchedEnvSuffix | undefined;\n    }\n\n    route = route.replace(/\\/index$/, \"\") || \"/\";\n\n    return {\n      handler: file.fullPath,\n      lazy: true,\n      middleware: false,\n      route,\n      method,\n      env,\n    };\n  });\n}\n\nexport async function scanPlugins(nitro: Nitro) {\n  const files = await scanFiles(nitro, \"plugins\");\n  return files.map((f) => f.fullPath);\n}\n\nexport async function scanTasks(nitro: Nitro) {\n  const files = await scanFiles(nitro, \"tasks\");\n  return files.map((f) => {\n    const name = f.path\n      .replace(/\\/index$/, \"\")\n      .replace(/\\.[A-Za-z]+$/, \"\")\n      .replace(/\\//g, \":\");\n    return { name, handler: f.fullPath };\n  });\n}\n\nexport async function scanModules(nitro: Nitro) {\n  const files = await scanFiles(nitro, \"modules\");\n  return files.map((f) => f.fullPath);\n}\n\nasync function scanFiles(nitro: Nitro, name: string): Promise<FileInfo[]> {\n  const files = await Promise.all(\n    nitro.options.scanDirs.map((dir) => scanDir(nitro, dir, name))\n  ).then((r) => r.flat());\n  return files;\n}\n\nasync function scanDir(nitro: Nitro, dir: string, name: string): Promise<FileInfo[]> {\n  const fileNames = await glob(join(name, GLOB_SCAN_PATTERN), {\n    cwd: dir,\n    dot: true,\n    ignore: nitro.options.ignore,\n    absolute: true,\n  }).catch((error) => {\n    if (error?.code === \"ENOTDIR\") {\n      nitro.logger.warn(`Ignoring \\`${join(dir, name)}\\`. It must be a directory.`);\n      return [];\n    }\n    throw error;\n  });\n  return fileNames\n    .map((fullPath) => {\n      return {\n        fullPath,\n        path: relative(join(dir, name), fullPath),\n      };\n    })\n    .sort((a, b) => a.path.localeCompare(b.path));\n}\n"
  },
  {
    "path": "src/task.ts",
    "content": "import http from \"node:http\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"pathe\";\nimport { withBase, withQuery } from \"ufo\";\n\nimport type { QueryObject } from \"ufo\";\nimport type { RequestOptions } from \"node:http\";\nimport type { NitroBuildInfo, TaskEvent, TaskRunnerOptions } from \"nitro/types\";\n\n/** @experimental */\nexport async function runTask(\n  taskEvent: TaskEvent,\n  opts?: TaskRunnerOptions\n): Promise<{ result: unknown }> {\n  const ctx = await _getTasksContext(opts);\n  const result = await ctx.devFetch(`/_nitro/tasks/${taskEvent.name}`, {\n    method: \"POST\",\n    body: taskEvent,\n  });\n  return result;\n}\n\n/** @experimental */\nexport async function listTasks(opts?: TaskRunnerOptions) {\n  const ctx = await _getTasksContext(opts);\n  const res = (await ctx.devFetch(\"/_nitro/tasks\")) as {\n    tasks: Record<string, { meta: { description: string } }>;\n  };\n  return res.tasks;\n}\n\n// --- module internal ---\n\nconst _devHint = `(is dev server running?)`;\n\nasync function _getTasksContext(opts?: TaskRunnerOptions) {\n  const cwd = resolve(process.cwd(), opts?.cwd || \".\");\n  const buildDir = resolve(cwd, opts?.buildDir || \"node_modules/.nitro\");\n\n  const buildInfoPath = resolve(buildDir, \"nitro.dev.json\");\n  if (!existsSync(buildInfoPath)) {\n    throw new Error(`Missing info file: \\`${buildInfoPath}\\` ${_devHint}`);\n  }\n\n  const buildInfo = JSON.parse(await readFile(buildInfoPath, \"utf8\")) as NitroBuildInfo;\n\n  if (!buildInfo.dev?.pid || !buildInfo.dev?.workerAddress) {\n    throw new Error(`Missing dev server info in: \\`${buildInfoPath}\\` ${_devHint}`);\n  }\n\n  if (!_pidIsRunning(buildInfo.dev.pid)) {\n    throw new Error(`Dev server is not running (pid: ${buildInfo.dev.pid})`);\n  }\n\n  const baseURL = `http://${buildInfo.dev.workerAddress.host || \"localhost\"}:${buildInfo.dev.workerAddress.port || \"3000\"}`;\n  const socketPath = buildInfo.dev.workerAddress.socketPath;\n\n  const devFetch = <T = any>(\n    path: string,\n    options?: {\n      method?: RequestOptions[\"method\"];\n      query?: QueryObject;\n      body?: unknown;\n    }\n  ) => {\n    return new Promise<T>((resolve, reject) => {\n      let url = withBase(path, baseURL);\n      if (options?.query) {\n        url = withQuery(url, options.query);\n      }\n\n      const request = http.request(\n        url,\n        {\n          socketPath,\n          method: options?.method,\n          headers: {\n            Accept: \"application/json\",\n            \"Content-Type\": \"application/json\",\n          },\n        },\n        (response) => {\n          if (!response.statusCode || (response.statusCode >= 400 && response.statusCode < 600)) {\n            reject(new Error(response.statusMessage));\n            return;\n          }\n\n          let data = \"\";\n          response\n            .on(\"data\", (chunk) => (data += chunk))\n            // Response of tasks is always JSON\n            .on(\"end\", () => resolve(JSON.parse(data)))\n            .on(\"error\", (e) => reject(e));\n        }\n      );\n\n      request.on(\"error\", (e) => reject(e));\n\n      if (options?.body) {\n        request.write(JSON.stringify(options.body));\n      }\n      request.end();\n    });\n  };\n\n  return {\n    buildInfo,\n    devFetch,\n  };\n}\n\nfunction _pidIsRunning(pid: number) {\n  try {\n    process.kill(pid, 0);\n    return true;\n  } catch {\n    return false;\n  }\n}\n"
  },
  {
    "path": "src/types/_utils.ts",
    "content": "export type Enumerate<N extends number, Acc extends number[] = []> = Acc[\"length\"] extends N\n  ? Acc[number]\n  : Enumerate<N, [...Acc, Acc[\"length\"]]>;\n\nexport type IntRange<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>>;\n\nexport type ExcludeFunctions<G extends Record<string, any>> = Pick<\n  G,\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n  { [P in keyof G]: NonNullable<G[P]> extends Function ? never : P }[keyof G]\n>;\n\nexport type KebabCase<T extends string, A extends string = \"\"> = T extends `${infer F}${infer R}`\n  ? KebabCase<R, `${A}${F extends Lowercase<F> ? \"\" : \"-\"}${Lowercase<F>}`>\n  : A;\n"
  },
  {
    "path": "src/types/build.ts",
    "content": "import type {\n  InputOptions as RollupInputOptions,\n  OutputOptions as RollupOutputOptions,\n} from \"rollup\";\n\nimport type {\n  InputOptions as RolldownInputOptions,\n  OutputOptions as RolldownOutputOptions,\n  MinifyOptions as RolldownMinifyOptions,\n  TransformOptions as RolldownTransformOptions,\n} from \"rolldown\";\n\nexport type RollupConfig = RollupInputOptions & {\n  output?: RollupOutputOptions;\n};\n\nexport type RolldownConfig = RolldownInputOptions & {\n  output?: RolldownOutputOptions;\n};\n\nexport interface OXCOptions {\n  minify?: RolldownMinifyOptions;\n  transform?: Omit<RolldownTransformOptions, \"jsx\"> & {\n    jsx?: Exclude<RolldownTransformOptions[\"jsx\"], false | string>;\n  };\n}\n"
  },
  {
    "path": "src/types/config.ts",
    "content": "import type commonjs from \"@rollup/plugin-commonjs\";\nimport type { C12InputConfig, ConfigWatcher, DotenvOptions, ResolvedConfig } from \"c12\";\nimport type { WatchConfigOptions } from \"c12\";\nimport type { ChokidarOptions } from \"chokidar\";\nimport type { CompatibilityDateSpec, CompatibilityDates } from \"compatx\";\nimport type { LogLevel } from \"consola\";\nimport type { ConnectorName } from \"db0\";\nimport type { NestedHooks } from \"hookable\";\nimport type { ProxyServerOptions } from \"httpxy\";\nimport type { PresetName, PresetNameInput, PresetOptions } from \"../presets/index.ts\";\nimport type { TSConfig } from \"pkg-types\";\nimport type { Preset as UnenvPreset } from \"unenv\";\nimport type { UnimportPluginOptions } from \"unimport/unplugin\";\nimport type { BuiltinDriverName } from \"unstorage\";\nimport type { UnwasmPluginOptions } from \"unwasm/plugin\";\nimport type { RunnerName } from \"env-runner\";\nimport type {\n  EventHandlerFormat,\n  NitroDevEventHandler,\n  NitroErrorHandler,\n  NitroEventHandler,\n} from \"./handler.ts\";\nimport type { NitroHooks } from \"./hooks.ts\";\nimport type { NitroModuleInput } from \"./module.ts\";\nimport type { NitroFrameworkInfo } from \"./nitro.ts\";\nimport type { NitroOpenAPIConfig } from \"./openapi.ts\";\nexport type { NitroOpenAPIConfig } from \"./openapi.ts\";\nimport type { NitroPreset } from \"./preset.ts\";\nimport type { OXCOptions, RolldownConfig } from \"./build.ts\";\nimport type { RollupConfig } from \"./build.ts\";\nimport type { NitroRouteConfig, NitroRouteRules } from \"./route-rules.ts\";\n\ntype RollupCommonJSOptions = NonNullable<Parameters<typeof commonjs.default>[0]>;\n\n/**\n * Nitro normalized options (nitro.options)\n */\nexport interface NitroOptions extends PresetOptions {\n  // Internal\n  _config: NitroConfig;\n  _c12: ResolvedConfig<NitroConfig> | ConfigWatcher<NitroConfig>;\n  _cli?: {\n    command?: string;\n  };\n\n  // Compatibility\n  compatibilityDate: CompatibilityDates;\n\n  // General\n  debug: boolean;\n  preset: PresetName;\n  static: boolean;\n  logLevel: LogLevel;\n  runtimeConfig: NitroRuntimeConfig;\n\n  // Dirs\n  workspaceDir: string;\n  rootDir: string;\n  serverDir: string | false;\n  scanDirs: string[];\n  apiDir: string;\n  routesDir: string;\n  buildDir: string;\n  output: {\n    dir: string;\n    serverDir: string;\n    publicDir: string;\n  };\n\n  /** @deprecated migrate to `serverDir` */\n  srcDir: string;\n\n  // Features\n  storage: StorageMounts;\n  devStorage: StorageMounts;\n  database: DatabaseConnectionConfigs;\n  devDatabase: DatabaseConnectionConfigs;\n  renderer?: { handler?: string; static?: boolean; template?: string };\n  ssrRoutes: string[];\n  serveStatic: boolean | \"node\" | \"deno\" | \"inline\";\n  noPublicDir: boolean;\n  manifest?: {\n    deploymentId?: string;\n  };\n  features: {\n    /**\n     * Enable runtime hooks for request and response.\n     *\n     * By default this feature will be enabled if there is at least one nitro plugin.\n     */\n    runtimeHooks?: boolean;\n\n    /**\n     * Enable WebSocket support\n     */\n    websocket?: boolean;\n  };\n\n  /**\n   *\n   * @see https://github.com/unjs/unwasm\n   */\n  wasm?: false | UnwasmPluginOptions;\n  openAPI?: NitroOpenAPIConfig;\n  experimental: {\n    openAPI?: boolean;\n    /**\n     * See https://github.com/microsoft/TypeScript/pull/51669\n     */\n    typescriptBundlerResolution?: boolean;\n    /**\n     * Enable native async context support for useRequest()\n     */\n    asyncContext?: boolean;\n    /**\n     * Disable Experimental Sourcemap Minification\n     */\n    sourcemapMinify?: false;\n    /**\n     * Allow env expansion in runtime config\n     *\n     * @see https://github.com/nitrojs/nitro/pull/2043\n     */\n    envExpansion?: boolean;\n    /**\n     * Enable WebSocket support\n     *\n     * @see https://nitro.build/guide/websocket\n     *\n     * @deprecated use `features.websocket` instead.\n     */\n    websocket?: boolean;\n    /**\n     * Enable experimental Database support\n     *\n     * @see https://nitro.build/guide/database\n     */\n    database?: boolean;\n    /**\n     * Enable experimental Tasks support\n     *\n     * @see https://nitro.build/guide/tasks\n     */\n    tasks?: boolean;\n  };\n  future: {\n    nativeSWR?: boolean;\n  };\n  serverAssets: ServerAssetDir[];\n  publicAssets: PublicAssetDir[];\n\n  imports: Partial<UnimportPluginOptions> | false;\n  modules?: NitroModuleInput[];\n  plugins: string[];\n  tasks: { [name: string]: { handler?: string; description?: string } };\n  scheduledTasks: { [cron: string]: string | string[] };\n  virtual: Record<string, string | (() => string | Promise<string>)>;\n  compressPublicAssets: boolean | CompressOptions;\n  ignore: string[];\n\n  // Dev\n  dev: boolean;\n  devServer: {\n    port?: number;\n    hostname?: string;\n    watch?: string[];\n    runner?: RunnerName;\n  };\n  watchOptions: ChokidarOptions;\n  devProxy: Record<string, string | ProxyServerOptions>;\n\n  // Logging\n  logging: {\n    compressedSizes?: boolean;\n    buildSuccess?: boolean;\n  };\n\n  // Routing\n  baseURL: string;\n  apiBaseURL: string;\n\n  serverEntry: false | { handler: string; format?: EventHandlerFormat };\n  handlers: NitroEventHandler[];\n  devHandlers: NitroDevEventHandler[];\n  routeRules: { [path: string]: NitroRouteRules };\n  routes: Record<string, string | Omit<NitroEventHandler, \"route\" | \"middleware\">>;\n\n  errorHandler: string | string[];\n  devErrorHandler: NitroErrorHandler;\n\n  prerender: {\n    /**\n     * Prerender HTML routes within subfolders (`/test` would produce `/test/index.html`)\n     */\n    autoSubfolderIndex?: boolean;\n    concurrency?: number;\n    interval?: number;\n    crawlLinks?: boolean;\n    failOnError?: boolean;\n    ignore?: Array<string | RegExp | ((path: string) => undefined | null | boolean)>;\n    ignoreUnprefixedPublicAssets?: boolean;\n    routes?: string[];\n    /**\n     * Amount of retries. Pass Infinity to retry indefinitely.\n     * @default 3\n     */\n    retry?: number;\n    /**\n     * Delay between each retry in ms.\n     * @default 500\n     */\n    retryDelay?: number;\n  };\n\n  // Rollup\n  builder?: \"rollup\" | \"rolldown\" | \"vite\";\n  rollupConfig?: RollupConfig;\n  rolldownConfig?: RolldownConfig;\n  entry: string;\n  unenv: UnenvPreset[];\n  alias: Record<string, string>;\n  minify: boolean;\n  inlineDynamicImports: boolean;\n  sourcemap: boolean;\n  node: boolean;\n  moduleSideEffects: string[];\n  oxc?: OXCOptions;\n  replace: Record<string, string | ((id: string) => string)>;\n  commonJS?: RollupCommonJSOptions;\n  exportConditions?: string[];\n  noExternals?: boolean | (string | RegExp)[];\n  traceDeps?: (string | RegExp)[];\n\n  // Advanced\n  typescript: {\n    strict?: boolean;\n    generateRuntimeConfigTypes?: boolean;\n    generateTsConfig?: boolean;\n    tsConfig?: Partial<TSConfig>;\n\n    /**\n     * Path of the generated types directory.\n     *\n     * Default is `node_modules/.nitro/types`\n     */\n    generatedTypesDir?: string;\n\n    /**\n     * Path of the generated `tsconfig.json` relative to `typescript.generatedTypesDir`\n     *\n     * Default is `tsconfig.json` (`node_modules/.nitro/types/tsconfig.json`)\n     */\n    tsconfigPath?: string;\n  };\n  hooks: NestedHooks<NitroHooks>;\n  commands: {\n    preview?: string;\n    deploy?: string;\n  };\n\n  // Framework\n  framework: NitroFrameworkInfo;\n\n  // IIS\n  iis?: {\n    mergeConfig?: boolean;\n    overrideConfig?: boolean;\n  };\n}\n\n/**\n * Nitro input config (nitro.config)\n */\nexport interface NitroConfig\n  extends\n    Partial<\n      Omit<\n        NitroOptions,\n        | \"routeRules\"\n        | \"rollupConfig\"\n        | \"preset\"\n        | \"compatibilityDate\"\n        | \"unenv\"\n        | \"serverDir\"\n        | \"_config\"\n        | \"_c12\"\n        | \"serverEntry\"\n        | \"renderer\"\n        | \"output\"\n      >\n    >,\n    C12InputConfig<NitroConfig> {\n  preset?: PresetNameInput;\n  extends?: string | string[] | NitroPreset;\n  routeRules?: { [path: string]: NitroRouteConfig };\n  rollupConfig?: Partial<RollupConfig>;\n  compatibilityDate?: CompatibilityDateSpec;\n  unenv?: UnenvPreset | UnenvPreset[];\n  serverDir?: boolean | \"./\" | \"./server\" | (string & {});\n  serverEntry?: string | NitroOptions[\"serverEntry\"];\n  renderer?: false | NitroOptions[\"renderer\"];\n  output?: Partial<NitroOptions[\"output\"]>;\n}\n\n// ------------------------------------------------------------\n// Config Loader\n// ------------------------------------------------------------\n\nexport interface LoadConfigOptions {\n  watch?: boolean;\n  c12?: WatchConfigOptions;\n  compatibilityDate?: CompatibilityDateSpec;\n  dotenv?: boolean | DotenvOptions;\n}\n\n// ------------------------------------------------------------\n// Partial types\n// ------------------------------------------------------------\n\n// Public assets\nexport interface PublicAssetDir {\n  baseURL?: string;\n  fallthrough?: boolean;\n  maxAge: number;\n  dir: string;\n  /**\n   * Pass false to disable ignore patterns when scanning the directory, or\n   * pass an array of glob patterns to ignore (which will override global\n   * nitro.ignore patterns).\n   */\n  ignore?: false | string[];\n}\n\n// Public assets compression\nexport interface CompressOptions {\n  gzip?: boolean;\n  brotli?: boolean;\n  zstd?: boolean;\n}\n\n// Server assets\nexport interface ServerAssetDir {\n  baseName: string;\n  pattern?: string;\n  dir: string;\n  ignore?: string[];\n}\n\n// Storage mounts\ntype CustomDriverName = string & { _custom?: any };\nexport interface StorageMounts {\n  [path: string]: {\n    driver: BuiltinDriverName | CustomDriverName;\n    [option: string]: any;\n  };\n}\n\n// Database\nexport type DatabaseConnectionName = \"default\" | (string & {});\nexport type DatabaseConnectionConfig = {\n  connector: ConnectorName;\n  options?: {\n    [key: string]: any;\n  };\n};\nexport type DatabaseConnectionConfigs = Record<DatabaseConnectionName, DatabaseConnectionConfig>;\n\n// Runtime config\n\nexport interface NitroRuntimeConfigApp {\n  [key: string]: any;\n}\n\nexport interface NitroRuntimeConfig {\n  nitro?: {\n    envPrefix?: string;\n    envExpansion?: boolean;\n    routeRules?: {\n      [path: string]: NitroRouteConfig;\n    };\n    openAPI?: NitroOpenAPIConfig;\n  };\n  [key: string]: any;\n}\n"
  },
  {
    "path": "src/types/fetch/_match.ts",
    "content": "import type { InternalApi } from \"./fetch.ts\";\n\ntype MatchResult<\n  Key extends string,\n  Exact extends boolean = false,\n  Score extends any[] = [],\n  catchAll extends boolean = false,\n> = {\n  [k in Key]: { key: k; exact: Exact; score: Score; catchAll: catchAll };\n}[Key];\n\ntype Subtract<Minuend extends any[] = [], Subtrahend extends any[] = []> = Minuend extends [\n  ...Subtrahend,\n  ...infer Remainder,\n]\n  ? Remainder\n  : never;\n\ntype TupleIfDiff<\n  First extends string,\n  Second extends string,\n  Tuple extends any[] = [],\n> = First extends `${Second}${infer Diff}` ? (Diff extends \"\" ? [] : Tuple) : [];\n\ntype MaxTuple<N extends any[] = [], T extends any[] = []> = {\n  current: T;\n  result: MaxTuple<N, [\"\", ...T]>;\n}[[N[\"length\"]] extends [Partial<T>[\"length\"]] ? \"current\" : \"result\"];\n\ntype CalcMatchScore<\n  Key extends string,\n  Route extends string,\n  Score extends any[] = [],\n  Init extends boolean = false,\n  FirstKeySegMatcher extends string = Init extends true ? \":Invalid:\" : \"\",\n> = `${Key}/` extends `${infer KeySeg}/${infer KeyRest}`\n  ? KeySeg extends FirstKeySegMatcher // return score if `KeySeg` is empty string (except first pass)\n    ? Subtract<[...Score, ...TupleIfDiff<Route, Key, [\"\", \"\"]>], TupleIfDiff<Key, Route, [\"\", \"\"]>>\n    : `${Route}/` extends `${infer RouteSeg}/${infer RouteRest}`\n      ? `${RouteSeg}?` extends `${infer RouteSegWithoutQuery}?${string}`\n        ? RouteSegWithoutQuery extends KeySeg\n          ? CalcMatchScore<KeyRest, RouteRest, [...Score, \"\", \"\"]> // exact match\n          : KeySeg extends `:${string}`\n            ? RouteSegWithoutQuery extends \"\"\n              ? never\n              : CalcMatchScore<KeyRest, RouteRest, [...Score, \"\"]> // param match\n            : KeySeg extends RouteSegWithoutQuery\n              ? CalcMatchScore<KeyRest, RouteRest, [...Score, \"\"]> // match by ${string}\n              : never\n        : never\n      : never\n  : never;\n\ntype _MatchedRoutes<\n  Route extends string,\n  MatchedResultUnion extends MatchResult<string> = MatchResult<keyof InternalApi>,\n> = MatchedResultUnion[\"key\"] extends infer MatchedKeys // spread union type\n  ? MatchedKeys extends string\n    ? Route extends MatchedKeys\n      ? MatchResult<MatchedKeys, true> // exact match\n      : MatchedKeys extends `${infer Root}/**${string}`\n        ? MatchedKeys extends `${string}/**`\n          ? Route extends `${Root}/${string}`\n            ? MatchResult<MatchedKeys, false, [], true>\n            : never // catchAll match\n          : MatchResult<MatchedKeys, false, CalcMatchScore<Root, Route, [], true>> // glob match\n        : MatchResult<MatchedKeys, false, CalcMatchScore<MatchedKeys, Route, [], true>> // partial match\n    : never\n  : never;\n\nexport type MatchedRoutes<\n  Route extends string,\n  MatchedKeysResult extends MatchResult<string> = MatchResult<keyof InternalApi>,\n  Matches extends MatchResult<string> = _MatchedRoutes<Route, MatchedKeysResult>,\n> = Route extends \"/\"\n  ? keyof InternalApi // root middleware\n  : Extract<Matches, { exact: true }> extends never\n    ? // @ts-ignore\n        | Extract<Exclude<Matches, { score: never }>, { score: MaxTuple<Matches[\"score\"]> }>[\"key\"]\n        | Extract<Matches, { catchAll: true }>[\"key\"] // partial, glob and catchAll matches\n    : Extract<Matches, { exact: true }>[\"key\"]; // exact matches\n"
  },
  {
    "path": "src/types/fetch/_serialize.ts",
    "content": "/**\n * @link https://github.com/remix-run/remix/blob/2248669ed59fd716e267ea41df5d665d4781f4a9/packages/remix-server-runtime/serialize.ts\n */\ntype JsonPrimitive = string | number | boolean | string | number | boolean | null;\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\ntype NonJsonPrimitive = undefined | Function | symbol;\n\n/*\n * `any` is the only type that can let you equate `0` with `1`\n * See https://stackoverflow.com/a/49928360/1490091\n */\ntype IsAny<T> = 0 extends 1 & T ? true : false;\n\ntype FilterKeys<TObj extends object, TFilter> = {\n  [TKey in keyof TObj]: TObj[TKey] extends TFilter ? TKey : never;\n}[keyof TObj];\n\n// prettier-ignore\nexport type Serialize<T> = IsAny<T> extends true\n  ? any\n  : T extends JsonPrimitive | undefined\n    ? T\n    : T extends Map<any, any> | Set<any>\n      ? Record<string, never>\n      : T extends NonJsonPrimitive\n        ? never\n        : T extends { toJSON(): infer U }\n          ? U\n          : T extends []\n            ? []\n            : T extends [unknown, ...unknown[]]\n              ? SerializeTuple<T>\n              : T extends ReadonlyArray<infer U>\n                ? (U extends NonJsonPrimitive ? null : Serialize<U>)[]\n                : T extends object\n                  ? SerializeObject<T>\n                  : never;\n\n/** JSON serialize [tuples](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types) */\nexport type SerializeTuple<T extends [unknown, ...unknown[]]> = {\n  [k in keyof T]: T[k] extends NonJsonPrimitive ? null : Serialize<T[k]>;\n};\n\n/** JSON serialize objects (not including arrays) and classes */\nexport type SerializeObject<T extends object> = {\n  [k in keyof Omit<T, FilterKeys<T, NonJsonPrimitive>>]: Serialize<T[k]>;\n};\n\n/**\n * @see https://github.com/ianstormtaylor/superstruct/blob/7973400cd04d8ad92bbdc2b6f35acbfb3c934079/src/utils.ts#L323-L325\n */\nexport type Simplify<TType> = TType extends any[] | Date\n  ? TType\n  : { [K in keyof TType]: Simplify<TType[K]> };\n"
  },
  {
    "path": "src/types/fetch/fetch.ts",
    "content": "import type { HTTPMethod } from \"h3\";\nimport type { FetchOptions, FetchRequest, FetchResponse } from \"ofetch\";\nimport type { MatchedRoutes } from \"./_match.ts\";\n\n// An interface to extend in a local project\nexport interface InternalApi {}\n\n// TODO: upgrade to uppercase for h3 v2 types and web consistency\ntype RouterMethod = Lowercase<HTTPMethod>;\n\nexport type NitroFetchRequest =\n  | Exclude<keyof InternalApi, `/_${string}` | `/api/_${string}`>\n  | Exclude<FetchRequest, string>\n  | (string & {});\n\nexport type MiddlewareOf<\n  Route extends string,\n  Method extends RouterMethod | \"default\",\n> = Method extends keyof InternalApi[MatchedRoutes<Route>]\n  ? InternalApi[MatchedRoutes<Route>][Method]\n  : never;\n\nexport type TypedInternalResponse<\n  Route,\n  Default = unknown,\n  Method extends RouterMethod = RouterMethod,\n> = Default extends string | boolean | number | null | void | object\n  ? // Allow user overrides\n    Default\n  : Route extends string\n    ? MiddlewareOf<Route, Method> extends never\n      ? MiddlewareOf<Route, \"default\"> extends never\n        ? // Bail if only types are Error or void (for example, from middleware)\n          Default\n        : MiddlewareOf<Route, \"default\">\n      : MiddlewareOf<Route, Method>\n    : Default;\n\n// Extracts the available http methods based on the route.\n// Defaults to all methods if there aren't any methods available or if there is a catch-all route.\nexport type AvailableRouterMethod<R extends NitroFetchRequest> = R extends string\n  ? keyof InternalApi[MatchedRoutes<R>] extends undefined\n    ? RouterMethod\n    : Extract<keyof InternalApi[MatchedRoutes<R>], \"default\"> extends undefined\n      ? Extract<RouterMethod, keyof InternalApi[MatchedRoutes<R>]>\n      : RouterMethod\n  : RouterMethod;\n\n// Argumented fetch options to include the correct request methods.\n// This overrides the default, which is only narrowed to a string.\nexport interface NitroFetchOptions<\n  R extends NitroFetchRequest,\n  M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>,\n> extends FetchOptions {\n  method?: Uppercase<M> | M;\n}\n\n// Extract the route method from options which might be undefined or without a method parameter.\nexport type ExtractedRouteMethod<\n  R extends NitroFetchRequest,\n  O extends NitroFetchOptions<R>,\n> = O extends undefined\n  ? \"get\"\n  : Lowercase<Exclude<O[\"method\"], undefined>> extends RouterMethod\n    ? Lowercase<Exclude<O[\"method\"], undefined>>\n    : \"get\";\n\nexport type Base$Fetch<\n  DefaultT = unknown,\n  DefaultR extends NitroFetchRequest = NitroFetchRequest,\n> = <\n  T = DefaultT,\n  R extends NitroFetchRequest = DefaultR,\n  O extends NitroFetchOptions<R> = NitroFetchOptions<R>,\n>(\n  request: R,\n  opts?: O\n) => Promise<\n  TypedInternalResponse<R, T, NitroFetchOptions<R> extends O ? \"get\" : ExtractedRouteMethod<R, O>>\n>;\n\nexport interface $Fetch<\n  DefaultT = unknown,\n  DefaultR extends NitroFetchRequest = NitroFetchRequest,\n> extends Base$Fetch<DefaultT, DefaultR> {\n  raw<\n    T = DefaultT,\n    R extends NitroFetchRequest = DefaultR,\n    O extends NitroFetchOptions<R> = NitroFetchOptions<R>,\n  >(\n    request: R,\n    opts?: O\n  ): Promise<\n    FetchResponse<\n      TypedInternalResponse<\n        R,\n        T,\n        NitroFetchOptions<R> extends O ? \"get\" : ExtractedRouteMethod<R, O>\n      >\n    >\n  >;\n  create<T = DefaultT, R extends NitroFetchRequest = DefaultR>(\n    defaults: FetchOptions\n  ): $Fetch<T, R>;\n}\n\n// eslint-disable-next-line unicorn/require-module-specifiers\nexport type {};\n"
  },
  {
    "path": "src/types/fetch/index.ts",
    "content": "export * from \"./_match.ts\";\nexport * from \"./_serialize.ts\";\nexport * from \"./fetch.ts\";\n"
  },
  {
    "path": "src/types/global.ts",
    "content": "import type { NitroOptions } from \"./config.ts\";\n\nexport interface NitroImportMeta {\n  dev?: boolean;\n  preset?: NitroOptions[\"preset\"];\n  prerender?: boolean;\n  nitro?: boolean;\n  server?: boolean;\n  client?: boolean;\n  baseURL?: string;\n  runtimeConfig?: Record<string, any>;\n  _asyncContext?: boolean;\n  _tasks?: boolean;\n  _websocket?: boolean;\n}\n\ndeclare global {\n  interface ImportMeta extends NitroImportMeta {}\n}\n\n// eslint-disable-next-line unicorn/require-module-specifiers\nexport type {};\n"
  },
  {
    "path": "src/types/h3.ts",
    "content": "import type { H3Event as _H3Event } from \"h3\";\nimport type { CacheOptions, CapturedErrorContext } from \"./runtime/index.ts\";\nimport type { Base$Fetch, NitroFetchRequest } from \"./fetch/fetch.ts\";\nimport type { NitroRuntimeConfig } from \"./config.ts\";\nimport type { MatchedRouteRules } from \"./route-rules.ts\";\n\nexport type H3EventFetch = (request: NitroFetchRequest, init?: RequestInit) => Promise<Response>;\n\nexport type H3Event$Fetch = Base$Fetch<unknown, NitroFetchRequest>;\n\ndeclare module \"srvx\" {\n  interface ServerRequestContext {\n    routeRules?: MatchedRouteRules;\n    nitro?: {\n      runtimeConfig?: NitroRuntimeConfig;\n      errors?: { error?: Error; context: CapturedErrorContext }[];\n    };\n    cache?: {\n      options?: CacheOptions;\n    };\n  }\n}\n\n// eslint-disable-next-line unicorn/require-module-specifiers\nexport type {};\n"
  },
  {
    "path": "src/types/handler.ts",
    "content": "import type { HTTPError, HTTPMethod, HTTPEvent, HTTPHandler } from \"h3\";\nimport type { PresetName } from \"../presets/index.ts\";\nimport type { OperationObject, OpenAPI3, Extensable } from \"../types/openapi-ts.ts\";\n\ntype MaybeArray<T> = T | T[];\n\n/** @experimental */\nexport interface NitroRouteMeta {\n  openAPI?: OperationObject & {\n    $global?: Pick<OpenAPI3, \"components\"> & Extensable;\n  };\n}\n\ninterface NitroHandlerCommon {\n  /**\n   * HTTP pathname pattern to match\n   *\n   * Examples: `/test`, `/api/:id`, `/blog/**`\n   */\n  route: string;\n\n  /**\n   * HTTP method to match\n   */\n  method?: HTTPMethod;\n\n  /**\n   * Run handler as a middleware before other route handlings\n   */\n  middleware?: boolean;\n\n  /**\n   * Extra Meta\n   */\n  meta?: NitroRouteMeta;\n}\n\nexport type EventHandlerFormat = \"web\" | \"node\";\n\nexport interface NitroEventHandler extends NitroHandlerCommon {\n  /**\n   * Use lazy loading to import handler\n   */\n  lazy?: boolean;\n\n  /**\n   * Path to event handler\n   */\n  handler: string;\n\n  /**\n   * Event handler type.\n   *\n   * Default is `\"web\"`. If set to `\"node\"`, the handler will be converted into a web compatible handler.\n   */\n  format?: EventHandlerFormat;\n\n  /*\n   * Environments to include and bundle this handler\n   */\n  env?: MaybeArray<\"dev\" | \"prod\" | \"prerender\" | PresetName | (string & {})>;\n}\n\nexport interface NitroDevEventHandler extends NitroHandlerCommon {\n  /**\n   * Event handler function\n   */\n  handler: HTTPHandler;\n}\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport type NitroErrorHandler = (\n  error: HTTPError,\n  event: HTTPEvent,\n  _: {\n    defaultHandler: (\n      error: HTTPError,\n      event: HTTPEvent,\n      opts?: { silent?: boolean; json?: boolean }\n    ) => MaybePromise<{\n      status?: number;\n      statusText?: string;\n      headers?: HeadersInit;\n      body?: string | Record<string, any>;\n    }>;\n  }\n) => MaybePromise<Response | void>;\n"
  },
  {
    "path": "src/types/hooks.ts",
    "content": "import type { EnvRunnerData } from \"env-runner\";\nimport type { NitroConfig } from \"./config.ts\";\nimport type { Nitro, NitroTypes } from \"./nitro.ts\";\nimport type { PrerenderRoute } from \"./prerender.ts\";\nimport type { RollupConfig } from \"./build.ts\";\n\ntype HookResult = void | Promise<void>;\n\nexport interface NitroHooks {\n  \"types:extend\": (types: NitroTypes) => HookResult;\n  \"build:before\": (nitro: Nitro) => HookResult;\n  \"rollup:before\": (nitro: Nitro, config: RollupConfig) => HookResult;\n  compiled: (nitro: Nitro) => HookResult;\n  \"dev:reload\": (payload?: { entry?: string; workerData?: EnvRunnerData }) => HookResult;\n  \"dev:start\": () => HookResult;\n  \"dev:error\": (cause?: unknown) => HookResult;\n  \"rollup:reload\": () => HookResult;\n  restart: () => HookResult;\n  close: () => HookResult;\n  // Prerender\n  \"prerender:routes\": (routes: Set<string>) => HookResult;\n  \"prerender:config\": (config: NitroConfig) => HookResult;\n  \"prerender:init\": (prerenderer: Nitro) => HookResult;\n  \"prerender:generate\": (route: PrerenderRoute, nitro: Nitro) => HookResult;\n  \"prerender:route\": (route: PrerenderRoute) => HookResult;\n  \"prerender:done\": (result: {\n    prerenderedRoutes: PrerenderRoute[];\n    failedRoutes: PrerenderRoute[];\n  }) => HookResult;\n}\n"
  },
  {
    "path": "src/types/index.ts",
    "content": "import \"nitro\";\nimport \"nitro/app\";\nimport \"nitro/cache\";\nimport \"nitro/context\";\nimport \"nitro/database\";\nimport \"nitro/h3\";\nimport \"nitro/runtime-config\";\nimport \"nitro/storage\";\nimport \"nitro/task\";\n\nexport * from \"./fetch/index.ts\";\nexport * from \"./runtime/index.ts\";\nexport * from \"./config.ts\";\nexport * from \"./runner.ts\";\nexport * from \"./global.ts\";\nexport * from \"./h3.ts\";\nexport * from \"./handler.ts\";\nexport * from \"./hooks.ts\";\nexport * from \"./module.ts\";\nexport * from \"./nitro.ts\";\nexport * from \"./prerender.ts\";\nexport * from \"./preset.ts\";\nexport * from \"./build.ts\";\nexport * from \"./route-rules.ts\";\nexport * from \"./srvx.ts\";\n"
  },
  {
    "path": "src/types/module.ts",
    "content": "import type { Nitro } from \"./nitro.ts\";\n\nexport type NitroModuleInput = string | NitroModule | NitroModule[\"setup\"] | { nitro: NitroModule };\n\nexport interface NitroModule {\n  name?: string;\n  setup: (this: void, nitro: Nitro) => void | Promise<void>;\n}\n"
  },
  {
    "path": "src/types/nitro.ts",
    "content": "import type { ConsolaInstance } from \"consola\";\nimport type { HTTPMethod } from \"h3\";\nimport type { Hookable } from \"hookable\";\nimport type { PresetName, PresetOptions } from \"../presets/index.ts\";\nimport type { Unimport } from \"unimport\";\nimport type { NitroConfig, NitroOptions } from \"./config.ts\";\nimport type { NitroEventHandler } from \"./handler.ts\";\nimport type { NitroHooks } from \"./hooks.ts\";\nimport type { PrerenderRoute } from \"./prerender.ts\";\nimport type { TSConfig } from \"pkg-types\";\nimport type { Router } from \"../routing.ts\";\nimport type { NitroRouteRules } from \"./route-rules.ts\";\nimport type { WorkerAddress } from \"./runner.ts\";\n\ntype MaybeArray<T> = T | T[];\n\nexport interface Nitro {\n  options: NitroOptions;\n  scannedHandlers: NitroEventHandler[];\n  vfs: Map<string, { render: () => string | Promise<string> }>;\n  hooks: Hookable<NitroHooks>;\n  unimport?: Unimport;\n  logger: ConsolaInstance;\n  fetch: (input: Request) => Response | Promise<Response>;\n  close: () => Promise<void>;\n  updateConfig: (config: NitroDynamicConfig) => void | Promise<void>;\n  routing: Readonly<{\n    sync: () => void;\n    routeRules: Router<NitroRouteRules & { _route: string }>;\n    routes: Router<MaybeArray<NitroEventHandler & { _importHash: string }>>;\n    globalMiddleware: (NitroEventHandler & { _importHash: string })[];\n    routedMiddleware: Router<NitroEventHandler & { _importHash: string }>;\n  }>;\n\n  /* @internal */\n  _prerenderedRoutes?: PrerenderRoute[];\n  _prerenderMeta?: Record<string, { contentType?: string }>;\n}\n\nexport type NitroDynamicConfig = Pick<NitroConfig, \"runtimeConfig\" | \"routeRules\">;\n\nexport type NitroTypes = {\n  routes: Record<string, Partial<Record<HTTPMethod | \"default\", string[]>>>;\n  tsConfig?: TSConfig;\n};\n\nexport interface NitroFrameworkInfo {\n  name?: \"nitro\" | (string & {});\n  version?: string;\n}\n\n/** Build info written to `.output/nitro.json` or `.nitro/dev/nitro.json` */\nexport interface NitroBuildInfo {\n  date: string;\n  preset: PresetName;\n  framework: NitroFrameworkInfo;\n  versions: {\n    nitro: string;\n    [key: string]: string;\n  };\n  commands?: {\n    preview?: string;\n    deploy?: string;\n  };\n  serverEntry?: string;\n  publicDir?: string;\n  dev?: {\n    pid: number;\n    workerAddress?: WorkerAddress;\n  };\n  config?: Partial<PresetOptions>;\n}\n"
  },
  {
    "path": "src/types/openapi-ts.ts",
    "content": "/**\nSource: (inlined because of install size concernes)\n\nhttps://github.com/openapi-ts/openapi-typescript/blob/fc3f7/packages/openapi-typescript/src/types.ts\n\nMIT License\n\nCopyright (c) 2020 Drew Powers\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n */\n\n// Many types allow for true “any” for inheritance to work\n\nexport interface Extensable {\n  [key: `x-${string}`]: any;\n}\n\n// Note: these OpenAPI types are meant only for internal use, not external\n// consumption. Some formatting may be better in other libraries meant for\n// consumption. Some typing may be “loose” or “incorrect” in order to guarantee\n// that all logical paths are handled. In other words, these are built more\n// for ways schemas _can_ be written, not necessarily how they _should_ be.\n\n/**\n * [4.8] Schema\n * @see https://spec.openapis.org/oas/v3.1.0#schema\n */\nexport interface OpenAPI3 extends Extensable {\n  /** REQUIRED. This string MUST be the version number of the OpenAPI Specification that the OpenAPI document uses. The openapi field SHOULD be used by tooling to interpret the OpenAPI document. This is not related to the API info.version string. */\n  openapi: string;\n  /** REQUIRED. Provides metadata about the API. The metadata MAY be used by tooling as required. */\n  info: InfoObject; // required\n  /** The default value for the $schema keyword within Schema Objects contained within this OAS document. This MUST be in the form of a URI. */\n  jsonSchemaDialect?: string;\n  /** An array of Server Objects, which provide connectivity information to a target server. If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of /. */\n  servers?: ServerObject[];\n  /** The available paths and operations for the API. */\n  paths?: PathsObject;\n  /** The incoming webhooks that MAY be received as part of this API and that the API consumer MAY choose to implement. Closely related to the callbacks feature, this section describes requests initiated other than by an API call, for example by an out of band registration. The key name is a unique string to refer to each webhook, while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider and the expected responses. An example is available. */\n  webhooks?: { [id: string]: PathItemObject | ReferenceObject };\n  /** An element to hold various schemas for the document. */\n  components?: ComponentsObject;\n  /** A declaration of which security mechanisms can be used across the API. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. Individual operations can override this definition. To make security optional, an empty security requirement ({}) can be included in the array. */\n  security?: SecurityRequirementObject[];\n  /** A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used by the Operation Object must be declared. The tags that are not declared MAY be organized randomly or based on the tools’ logic. Each tag name in the list MUST be unique. */\n  tags?: TagObject[];\n  /** Additional external documentation. */\n  externalDocs?: ExternalDocumentationObject;\n  $defs?: $defs;\n}\n\n/**\n * [4.8.2] Info Object\n * The object provides metadata about the API.\n */\nexport interface InfoObject extends Extensable {\n  /** REQUIRED. The title of the API. */\n  title: string;\n  /** A short summary of the API. */\n  summary?: string;\n  /** A description of the API. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** A URL to the Terms of Service for the API. This MUST be in the form of a URL. */\n  termsOfService?: string;\n  /** The contact information for the exposed API. */\n  contact?: ContactObject;\n  /** The license information for the exposed API. */\n  license?: LicenseObject;\n  /** REQUIRED. The version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the API implementation version). */\n  version: string;\n}\n\n/**\n * [4.8.3] Contact Object\n * Contact information for the exposed API.\n */\nexport interface ContactObject extends Extensable {\n  /** The identifying name of the contact person/organization. */\n  name?: string;\n  /** The URL pointing to the contact information. This MUST be in the form of a URL. */\n  url?: string;\n  /** The email address of the contact person/organization. This MUST be in the form of an email address. */\n  email?: string;\n}\n\n/**\n * [4.8.4] License object\n * License information for the exposed API.\n */\nexport interface LicenseObject extends Extensable {\n  /** REQUIRED. The license name used for the API. */\n  name: string;\n  /** An SPDX license expression for the API. The identifier field is mutually exclusive of the url field. */\n  identifier: string;\n  /** A URL to the license used for the API. This MUST be in the form of a URL. The url field is mutually exclusive of the identifier field. */\n  url: string;\n}\n\n/**\n * [4.8.5] Server Object\n * An object representing a Server.\n */\nexport interface ServerObject extends Extensable {\n  /** REQUIRED. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the OpenAPI document is being served. Variable substitutions will be made when a variable is named in {brackets}. */\n  url: string;\n  /** An optional string describing the host designated by the URL. CommonMark syntax MAY be used for rich text representation. */\n  description: string;\n  /** A map between a variable name and its value. The value is used for substitution in the server’s URL template. */\n  variables: { [name: string]: ServerVariableObject };\n}\n\n/**\n * [4.8.6] Server Variable Object\n * An object representing a Server Variable for server URL template substitution.\n */\nexport interface ServerVariableObject extends Extensable {\n  /** An enumeration of string values to be used if the substitution options are from a limited set. The array MUST NOT be empty. */\n  enum?: string[];\n  /** REQUIRED. The default value to use for substitution, which SHALL be sent if an alternate value is not supplied. Note this behavior is different than the Schema Object’s treatment of default values, because in those cases parameter values are optional. If the enum is defined, the value MUST exist in the enum’s values. */\n  default: string;\n  /** An optional description for the server variable. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n}\n\n/**\n * [4.8.7] Components Object\n * Holds a set of reusable objects for different aspects of the OAS.\n */\nexport interface ComponentsObject extends Extensable {\n  /** An object to hold reusable Schema Objects.*/\n  schemas?: Record<string, SchemaObject>;\n  /** An object to hold reusable Response Objects. */\n  responses?: Record<string, ResponseObject | ReferenceObject>;\n  /** An object to hold reusable Parameter Objects. */\n  parameters?: Record<string, ParameterObject | ReferenceObject>;\n  /** An object to hold reusable Example Objects. */\n  examples?: Record<string, ExampleObject | ReferenceObject>;\n  /** An object to hold reusable Request Body Objects. */\n  requestBodies?: Record<string, RequestBodyObject | ReferenceObject>;\n  /** An object to hold reusable Header Objects. */\n  headers?: Record<string, HeaderObject | ReferenceObject>;\n  /** An object to hold reusable Security Scheme Objects. */\n  securitySchemes?: Record<string, SecuritySchemeObject | ReferenceObject>;\n  /** An object to hold reusable Link Objects. */\n  links?: Record<string, LinkObject | ReferenceObject>;\n  /** An object to hold reusable Callback Objects. */\n  callbacks?: Record<string, CallbackObject | ReferenceObject>;\n  /** An object to hold reusable Path Item Objects. */\n  pathItems?: Record<string, PathItemObject | ReferenceObject>;\n}\n\n/**\n * [4.8.8] Paths Object\n * Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the Server Object in order to construct the full URL. The Paths MAY be empty, due to Access Control List (ACL) constraints.\n */\nexport interface PathsObject {\n  [pathname: string]: PathItemObject | ReferenceObject; // note: paths object does support $refs; the schema just defines it in a weird way\n}\n\n/**\n * [x.x.x] Webhooks Object\n * Holds the webhooks definitions, indexed by their names. A webhook is defined by a Path Item Object; the only difference is that the request is initiated by the API provider.\n */\nexport interface WebhooksObject {\n  [name: string]: PathItemObject;\n}\n\n/**\n * [4.8.9] Path Item Object\n * Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.\n */\nexport interface PathItemObject extends Extensable {\n  /** A definition of a GET operation on this path. */\n  get?: OperationObject | ReferenceObject;\n  /** A definition of a PUT operation on this path. */\n  put?: OperationObject | ReferenceObject;\n  /** A definition of a POST operation on this path. */\n  post?: OperationObject | ReferenceObject;\n  /** A definition of a DELETE operation on this path. */\n  delete?: OperationObject | ReferenceObject;\n  /** A definition of a OPTIONS operation on this path. */\n  options?: OperationObject | ReferenceObject;\n  /** A definition of a HEAD operation on this path. */\n  head?: OperationObject | ReferenceObject;\n  /** A definition of a PATCH operation on this path. */\n  patch?: OperationObject | ReferenceObject;\n  /** A definition of a TRACE operation on this path. */\n  trace?: OperationObject | ReferenceObject;\n  /** An alternative server array to service all operations in this path. */\n  servers?: ServerObject[];\n  /** A list of parameters that are applicable for all the operations described under this path. These parameters can be overridden at the operation level, but cannot be removed there. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object’s components/parameters. */\n  parameters?: (ParameterObject | ReferenceObject)[];\n}\n\n/**\n * [4.8.10] Operation Object\n * Describes a single API operation on a path.\n */\nexport interface OperationObject extends Extensable {\n  /** A list of tags for API documentation control. Tags can be used for logical grouping of operations by resources or any other qualifier. */\n  tags?: string[];\n  /** A short summary of what the operation does. */\n  summary?: string;\n  /** A verbose explanation of the operation behavior. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** Additional external documentation for this operation. */\n  externalDocs?: ExternalDocumentationObject;\n  /** Unique string used to identify the operation. The id MUST be unique among all operations described in the API. The operationId value is case-sensitive. Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is RECOMMENDED to follow common programming naming conventions. */\n  operationId?: string;\n  /** A list of parameters that are applicable for this operation. If a parameter is already defined at the Path Item, the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object’s components/parameters. */\n  parameters?: (ParameterObject | ReferenceObject)[];\n  /** The request body applicable for this operation. The requestBody is fully supported in HTTP methods where the HTTP 1.1 specification [RFC7231] has explicitly defined semantics for request bodies. In other cases where the HTTP spec is vague (such as GET, HEAD and DELETE), requestBody is permitted but does not have well-defined semantics and SHOULD be avoided if possible. */\n  requestBody?: RequestBodyObject | ReferenceObject;\n  /** The list of possible responses as they are returned from executing this operation. */\n  responses?: ResponsesObject;\n  /** A map of possible out-of band callbacks related to the parent operation. The key is a unique identifier for the Callback Object. Each value in the map is a Callback Object that describes a request that may be initiated by the API provider and the expected responses. */\n  callbacks?: Record<string, CallbackObject | ReferenceObject>;\n  /** Declares this operation to be deprecated. Consumers SHOULD refrain from usage of the declared operation. Default value is false. */\n  deprecated?: boolean;\n  /** A declaration of which security mechanisms can be used for this operation. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. To make security optional, an empty security requirement ({}) can be included in the array. This definition overrides any declared top-level security. To remove a top-level security declaration, an empty array can be used. */\n  security?: SecurityRequirementObject[];\n  /** An alternative server array to service this operation. If an alternative server object is specified at the Path Item Object or Root level, it will be overridden by this value. */\n  servers?: ServerObject[];\n}\n\n/**\n * [4.8.11] External Documentation Object\n * Allows referencing an external resource for extended documentation.\n */\nexport interface ExternalDocumentationObject extends Extensable {\n  /** A description of the target documentation. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** REQUIRED. The URL for the target documentation. This MUST be in the form of a URL. */\n  url: string;\n}\n\n/**\n * [4.8.12] Parameter Object\n * Describes a single operation parameter.\n * A unique parameter is defined by a combination of a name and location.\n */\nexport interface ParameterObject extends Extensable {\n  /**\n   * REQUIRED. The name of the parameter. Parameter names are case sensitive.\n   *\n   * - If `in` is `\"path\"`, the `name` field MUST correspond to a template expression occurring within the path field in the Paths Object. See Path Templating for further information.\n   * - If `in` is `\"header\"` and the `name` field is `\"Accept\"`, `\"Content-Type\"` or `\"Authorization\"`, the parameter definition SHALL be ignored.\n   * - For all other cases, the `name` corresponds to the parameter name used by the `in` property.\n   */\n  name: string;\n  /** REQUIRED. The location of the parameter. Possible values are \"query\", \"header\", \"path\" or \"cookie\".*/\n  in: \"query\" | \"header\" | \"path\" | \"cookie\";\n  /** A brief description of the parameter. This could contain examples of use. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** Determines whether this parameter is mandatory. If the parameter location is \"path\", this property is REQUIRED and its value MUST be true. Otherwise, the property MAY be included and its default value is false. */\n  required?: boolean;\n  /** Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is false. */\n  deprecated?: boolean;\n  /** Sets the ability to pass empty-valued parameters. This is valid only for query parameters and allows sending a parameter with an empty value. Default value is false. If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored. Use of this property is NOT RECOMMENDED, as it is likely to be removed in a later revision. */\n  allowEmptyValue?: boolean;\n  /** Describes how the parameter value will be serialized depending on the type of the parameter value. Default values (based on value of in): for query - form; for path - simple; for header - simple; for cookie - form. */\n  style?: string;\n  /** When this is true, parameter values of type `array` or `object` generate separate parameters for each value of the array or key-value pair of the map. For other types of parameters this property has no effect. When `style` is `form`, the default value is `true`. For all other styles, the default value is `false`. */\n  explode?: boolean;\n  /** Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986] `:/?#[]@!$&'()*+,;=` to be included without percent-encoding. This property only applies to parameters with an `in` value of `query`. The default value is `false`. */\n  allowReserved?: boolean;\n  /** The schema defining the type used for the parameter. */\n  schema?: SchemaObject;\n  /** Example of the parameter’s potential value. */\n  example?: any;\n  /** Examples of the parameter’s potential value. */\n  examples?: { [name: string]: ExampleObject | ReferenceObject };\n  /** A map containing the representations for the parameter. */\n  content?: { [contentType: string]: MediaTypeObject | ReferenceObject };\n}\n\n/**\n * [4.8.13] Request Body Object\n * Describes a single request body.\n */\nexport interface RequestBodyObject extends Extensable {\n  /** A brief description of the request body. This could contain examples of use. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** REQUIRED. The content of the request body. The key is a media type or media type range and the value describes it. For requests that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text */\n  content: { [contentType: string]: MediaTypeObject | ReferenceObject };\n  /** Determines if the request body is required in the request. Defaults to false. */\n  required?: boolean;\n}\n\n/**\n * [4.8.14] Media Type Object\n */\nexport interface MediaTypeObject extends Extensable {\n  /** The schema defining the content of the request, response, or parameter. */\n  schema?: SchemaObject | ReferenceObject;\n  /** Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example field is mutually exclusive of the examples field. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema. */\n  example?: any;\n  /** Examples of the media type. Each example object SHOULD match the media type and specified schema if present. The examples field is mutually exclusive of the example field. Furthermore, if referencing a schema which contains an example, the examples value SHALL override the example provided by the schema. */\n  examples?: { [name: string]: ExampleObject | ReferenceObject };\n  /** A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to requestBody objects when the media type is multipart or application/x-www-form-urlencoded. */\n  encoding?: { [propertyName: string]: EncodingObject };\n}\n\n/**\n * [4.8.15] Encoding Object\n * A single encoding definition applied to a single schema property.\n */\nexport interface EncodingObject extends Extensable {\n  /** The Content-Type for encoding a specific property. Default value depends on the property type: for object - application/json; for array – the default is defined based on the inner type; for all other cases the default is application/octet-stream. The value can be a specific media type (e.g. application/json), a wildcard media type (e.g. image/*), or a comma-separated list of the two types. */\n  contentType?: string;\n  /** A map allowing additional information to be provided as headers, for example Content-Disposition. Content-Type is described separately and SHALL be ignored in this section. This property SHALL be ignored if the request body media type is not a multipart. */\n  headers?: { [name: string]: HeaderObject | ReferenceObject };\n  /** Describes how a specific property value will be serialized depending on its type. See Parameter Object for details on the style property. The behavior follows the same values as query parameters, including default values. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded or multipart/form-data. If a value is explicitly defined, then the value of contentType (implicit or explicit) SHALL be ignored. */\n  style?: string;\n  /** When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect. When style is form, the default value is true. For all other styles, the default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded or multipart/form-data. If a value is explicitly defined, then the value of contentType (implicit or explicit) SHALL be ignored. */\n  explode?: string;\n  /** Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986] :/?#[]@!$&'()*+,;= to be included without percent-encoding. The default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded or multipart/form-data. If a value is explicitly defined, then the value of contentType (implicit or explicit) SHALL be ignored. */\n  allowReserved?: string;\n}\n\n/**\n * [4.8.16] Responses Object\n * A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.\n */\nexport type ResponsesObject = {\n  [responseCode: string]: ResponseObject | ReferenceObject;\n} & {\n  /** The documentation of responses other than the ones declared for specific HTTP response codes. Use this field to cover undeclared responses. */\n  default?: ResponseObject | ReferenceObject;\n};\n\n/**\n * [4.8.17] Response Object\n * Describes a single response from an API Operation, including design-time, static links to operations based on the response.\n */\nexport interface ResponseObject extends Extensable {\n  /** REQUIRED. A description of the response. CommonMark syntax MAY be used for rich text representation. */\n  description: string;\n  /** Maps a header name to its definition. [RFC7230] states header names are case insensitive. If a response header is defined with the name \"Content-Type\", it SHALL be ignored. */\n  headers?: { [name: string]: HeaderObject | ReferenceObject };\n  /** A map containing descriptions of potential response payloads. The key is a media type or media type range and the value describes it. For responses that match multiple keys, only the most specific key is applicable. e.g. text/plain overrides text */\n  content?: { [contentType: string]: MediaTypeObject };\n  /** A map of operations links that can be followed from the response. The key of the map is a short name for the link, following the naming constraints of the names for Component Objects. */\n  links?: { [name: string]: LinkObject | ReferenceObject };\n}\n\n/**\n * [4.8.18] Callback Object\n * A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the path item object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.\n */\nexport type CallbackObject = Record<string, PathItemObject>;\n\n/**\n * [4.8.19[ Example Object\n */\nexport interface ExampleObject extends Extensable {\n  /** Short description for the example. */\n  summary?: string;\n  /** Long description for the example. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** Embedded literal example. The value field and externalValue field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary. */\n  value?: any;\n  /** A URI that points to the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents. The value field and externalValue field are mutually exclusive. See the rules for resolving Relative References. */\n  externalValue?: string;\n}\n\n/**\n * [4.8.20] Link Object\n * The Link object represents a possible design-time link for a response. The presence of a link does not guarantee the caller’s ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.\n */\nexport interface LinkObject extends Extensable {\n  /** A relative or absolute URI reference to an OAS operation. This field is mutually exclusive of the operationId field, and MUST point to an Operation Object. Relative operationRef values MAY be used to locate an existing Operation Object in the OpenAPI definition. See the rules for resolving Relative References. */\n  operationRef?: string;\n  /** The name of an existing, resolvable OAS operation, as defined with a unique operationId. This field is mutually exclusive of the operationRef field. */\n  operationId?: string;\n  /** A map representing parameters to pass to an operation as specified with operationId or identified via operationRef. The key is the parameter name to be used, whereas the value can be a constant or an expression to be evaluated and passed to the linked operation. The parameter name can be qualified using the parameter location [{in}.]{name} for operations that use the same parameter name in different locations (e.g. path.id). */\n  parameters?: { [name: string]: `$${string}` };\n  /** A literal value or {expression} to use as a request body when calling the target operation. */\n  requestBody?: `$${string}`;\n  /** A description of the link. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** A server object to be used by the target operation. */\n  server?: ServerObject;\n}\n\n/**\n * [4.8.21] Header Object\n * The Header Object follows the structure of the Parameter Object with the following changes:\n *\n * 1. `name` MUST NOT be specified, it is given in the corresponding `headers` map.\n * 2. `in` MUST NOT be specified, it is implicitly in `header`.\n * 3. All traits that are affected by the location MUST be applicable to a location of `heade`r (for example, `style`).\n */\nexport type HeaderObject = Omit<ParameterObject, \"name\" | \"in\">;\n\n/**\n * [4.8.22] Tag Object\n * Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.\n */\nexport interface TagObject extends Extensable {\n  /** REQUIRED. The name of the tag. */\n  name: string;\n  /** A description for the tag. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  /** Additional external documentation for this tag. */\n  externalDocs?: ExternalDocumentationObject;\n}\n\n/**\n * [4.8.23] Reference Object\n * A simple object to allow referencing other components in the OpenAPI document, internally and externally. The $ref string value contains a URI [RFC3986], which identifies the location of the value being referenced. See the rules for resolving Relative References.\n */\nexport interface ReferenceObject extends Extensable {\n  /** REQUIRED. The reference identifier. This MUST be in the form of a URI. */\n  $ref: string;\n  /** A short summary which by default SHOULD override that of the referenced component. If the referenced object-type does not allow a summary field, then this field has no effect. */\n  summary?: string;\n  /** A description which by default SHOULD override that of the referenced component. CommonMark syntax MAY be used for rich text representation. If the referenced object-type does not allow a description field, then this field has no effect. */\n  description?: string;\n}\n\n/**\n * [4.8.24] Schema Object\n * The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is a superset of the JSON Schema Specification Draft 2020-12.\n */\nexport type SchemaObject = {\n  /** The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is a superset of the JSON Schema Specification Draft 2020-12. */\n  discriminator?: DiscriminatorObject;\n  /** MAY be used only on properties schemas. It has no effect on root schemas. Adds additional metadata to describe the XML representation of this property. */\n  xml?: XMLObject;\n  /** Additional external documentation for this schema. */\n  externalDocs?: ExternalDocumentationObject;\n  /** @deprecated */\n  example?: any;\n  title?: string;\n  description?: string;\n  $comment?: string;\n  deprecated?: boolean;\n  readOnly?: boolean;\n  writeOnly?: boolean;\n  enum?: unknown[];\n  /** Use of this keyword is functionally equivalent to an \"enum\" (Section 6.1.2) with a single value. */\n  const?: unknown;\n  default?: unknown;\n  format?: string;\n  /** @deprecated in 3.1 (still valid for 3.0) */\n  nullable?: boolean;\n  oneOf?: (SchemaObject | ReferenceObject)[];\n  allOf?: (SchemaObject | ReferenceObject)[];\n  anyOf?: (SchemaObject | ReferenceObject)[];\n  required?: string[];\n  [key: `x-${string}`]: any;\n} & (\n  | StringSubtype\n  | NumberSubtype\n  | IntegerSubtype\n  | ArraySubtype\n  | BooleanSubtype\n  | NullSubtype\n  | ObjectSubtype\n  | {\n      type: (\"string\" | \"number\" | \"integer\" | \"array\" | \"boolean\" | \"null\" | \"object\")[];\n    }\n);\n\nexport interface StringSubtype {\n  type: \"string\" | [\"string\", \"null\"];\n  enum?: (string | ReferenceObject)[];\n}\n\nexport interface NumberSubtype {\n  type: \"number\" | [\"number\", \"null\"];\n  minimum?: number;\n  maximum?: number;\n  enum?: (number | ReferenceObject)[];\n}\n\nexport interface IntegerSubtype {\n  type: \"integer\" | [\"integer\", \"null\"];\n  minimum?: number;\n  maximum?: number;\n  enum?: (number | ReferenceObject)[];\n}\n\nexport interface ArraySubtype {\n  type: \"array\" | [\"array\", \"null\"];\n  prefixItems?: (SchemaObject | ReferenceObject)[];\n  items?: SchemaObject | ReferenceObject | (SchemaObject | ReferenceObject)[];\n  minItems?: number;\n  maxItems?: number;\n  enum?: (SchemaObject | ReferenceObject)[];\n}\n\nexport interface BooleanSubtype {\n  type: \"boolean\" | [\"boolean\", \"null\"];\n  enum?: (boolean | ReferenceObject)[];\n}\n\nexport interface NullSubtype {\n  type: \"null\";\n}\n\nexport interface ObjectSubtype {\n  type: \"object\" | [\"object\", \"null\"];\n  properties?: { [name: string]: SchemaObject | ReferenceObject };\n  additionalProperties?: boolean | Record<string, never> | SchemaObject | ReferenceObject;\n  required?: string[];\n  allOf?: (SchemaObject | ReferenceObject)[];\n  anyOf?: (SchemaObject | ReferenceObject)[];\n  enum?: (SchemaObject | ReferenceObject)[];\n  $defs?: $defs;\n}\n\n/**\n * [4.8.25] Discriminator Object\n * When request bodies or response payloads may be one of a number of different schemas, a discriminator object can be used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used to inform the consumer of the document of an alternative schema based on the value associated with it.\n */\nexport interface DiscriminatorObject {\n  /** REQUIRED. The name of the property in the payload that will hold the discriminator value. */\n  propertyName: string;\n  /** An object to hold mappings between payload values and schema names or references. */\n  mapping?: Record<string, string>;\n  /** If this exists, then a discriminator type should be added to objects matching this path */\n  oneOf?: string[];\n}\n\n/**\n * [4.8.26] XML Object\n * A metadata object that allows for more fine-tuned XML model definitions. When using arrays, XML element names are not inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.\n */\nexport interface XMLObject extends Extensable {\n  /** Replaces the name of the element/attribute used for the described schema property. When defined within `items`, it will affect the name of the individual XML elements within the list. When defined alongside `type` being `array` (outside the `items`), it will affect the wrapping element and only if `wrapped` is `true`. If `wrapped` is `false`, it will be ignored. */\n  name?: string;\n  /** The URI of the namespace definition. This MUST be in the form of an absolute URI. */\n  namespace?: string;\n  /** The prefix to be used for the name. */\n  prefix?: string;\n  /** Declares whether the property definition translates to an attribute instead of an element. Default value is `false`. */\n  attribute?: boolean;\n  /** MAY be used only for an array definition. Signifies whether the array is wrapped (for example, `<books><book/><book/></books>`) or unwrapped (`<book/><book/>`). Default value is `false`. The definition takes effect only when defined alongside `type` being `array` (outside the `items`). */\n  wrapped?: boolean;\n}\n\n/**\n * [4.8.27] Security Scheme Object\n * Defines a security scheme that can be used by the operations.\n */\nexport type SecuritySchemeObject = {\n  /** A description for security scheme. CommonMark syntax MAY be used for rich text representation. */\n  description?: string;\n  [key: `x-${string}`]: any;\n} & (\n  | {\n      /** REQUIRED. The type of the security scheme. */\n      type: \"apiKey\";\n      /** REQUIRED. The name of the header, query or cookie parameter to be used. */\n      name: string;\n      /** REQUIRED. The location of the API key. */\n      in: \"query\" | \"header\" | \"cookie\";\n    }\n  | {\n      /** REQUIRED. The type of the security scheme. */\n      type: \"http\";\n      /** REQUIRED. The name of the HTTP Authorization scheme to be used in the Authorization header as defined in [RFC7235]. The values used SHOULD be registered in the IANA Authentication Scheme registry. */\n      scheme: string;\n      /** A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes. */\n      bearer?: string;\n    }\n  | {\n      /** REQUIRED. The type of the security scheme. */\n      type: \"mutualTLS\";\n    }\n  | {\n      /** REQUIRED. Tye type of the security scheme. */\n      type: \"oauth2\";\n      /** REQUIRED. An object containing configuration information for the flow types supported. */\n      flows: OAuthFlowsObject;\n    }\n  | {\n      /** REQUIRED. Tye type of the security scheme. */\n      type: \"openIdConnect\";\n      /** REQUIRED. OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of a URL. The OpenID Connect standard requires the use of TLS. */\n      openIdConnectUrl: string;\n    }\n);\n\n/**\n * [4.8.26] OAuth Flows Object\n * Allows configuration of the supported OAuth Flows.\n */\nexport interface OAuthFlowsObject extends Extensable {\n  /** Configuration for the OAuth Implicit flow */\n  implicit?: OAuthFlowObject;\n  /** Configuration for the OAuth Resource Owner Password flow */\n  password?: OAuthFlowObject;\n  /** Configuration for the OAuth Client Credentials flow. Previously called `application` in OpenAPI 2.0. */\n  clientCredentials?: OAuthFlowObject;\n  /** Configuration for the OAuth Authorization Code flow. Previously called `accessCode` in OpenAPI 2.0. */\n  authorizationCode?: OAuthFlowObject;\n}\n\n/**\n * [4.8.29] OAuth Flow Object\n * Configuration details for a supported OAuth Flow\n */\nexport interface OAuthFlowObject extends Extensable {\n  /** REQUIRED. The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. */\n  authorizationUrl: string;\n  /** REQUIRED. The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. */\n  tokenUrl: string;\n  /** The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS. */\n  refreshUrl: string;\n  /** REQUIRED. The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty. */\n  scopes: { [name: string]: string };\n}\n\n/**\n * [4.8.30] Security Requirements Object\n * Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.\n */\nexport type SecurityRequirementObject = {\n  [P in keyof ComponentsObject[\"securitySchemes\"]]?: string[];\n};\n\nexport type $defs = Record<string, SchemaObject>;\n"
  },
  {
    "path": "src/types/openapi.ts",
    "content": "// import type { ApiReferenceConfiguration as ScalarConfig } from \"@scalar/api-reference\";\n\n/**\n * Nitro OpenAPI configuration\n */\nexport interface NitroOpenAPIConfig {\n  /**\n   * OpenAPI meta information\n   */\n  meta?: {\n    title?: string;\n    description?: string;\n    version?: string;\n  };\n\n  /**\n   * OpenAPI json route\n   *\n   * Default is `/_openapi.json`\n   */\n  route?: string;\n\n  /**\n   * Enable OpenAPI generation for production builds\n   */\n  production?: false | \"runtime\" | \"prerender\";\n\n  /**\n   * UI configurations\n   */\n  ui?: {\n    /**\n     * Scalar UI configuration\n     */\n    scalar?:\n      | false\n      | (Partial<unknown> & {\n          /**\n           * Scalar UI route\n           *\n           * Default is `/_scalar`\n           */\n          route?: string;\n        });\n    /**\n     * Swagger UI configuration\n     */\n    swagger?:\n      | false\n      | {\n          /**\n           * Swagger UI route\n           *\n           * Default is `/_swagger`\n           */\n          route?: string;\n        };\n  };\n}\n"
  },
  {
    "path": "src/types/prerender.ts",
    "content": "import type { HTTPError } from \"h3\";\n\nexport interface PrerenderRoute {\n  route: string;\n  contents?: string;\n  data?: ArrayBuffer;\n  fileName?: string;\n  error?: Partial<HTTPError>;\n  generateTimeMS?: number;\n  skip?: boolean;\n  contentType?: string;\n}\n\n/** @deprecated Internal type will be removed in future versions */\nexport type PrerenderGenerateRoute = PrerenderRoute;\n"
  },
  {
    "path": "src/types/preset.ts",
    "content": "import type { DateString } from \"compatx\";\nimport type { ProviderName } from \"std-env\";\nimport type { NitroConfig } from \"./config.ts\";\n\nexport type NitroPreset = NitroConfig | (() => NitroConfig);\n\nexport interface NitroPresetMeta {\n  name: string;\n  stdName?: ProviderName;\n  aliases?: string[];\n  static?: boolean;\n  dev?: boolean;\n  compatibilityDate?: DateString;\n}\n"
  },
  {
    "path": "src/types/route-rules.ts",
    "content": "import type { Middleware, ProxyOptions, BasicAuthOptions } from \"h3\";\nimport type { ExcludeFunctions, IntRange } from \"./_utils.ts\";\nimport type { CachedEventHandlerOptions } from \"./runtime/index.ts\";\n\nexport type HTTPstatus = IntRange<100, 600>;\n\nexport interface NitroRouteConfig {\n  cache?: ExcludeFunctions<CachedEventHandlerOptions> | false;\n  headers?: Record<string, string>;\n  redirect?: string | { to: string; status?: HTTPstatus };\n  prerender?: boolean;\n  proxy?: string | ({ to: string } & ProxyOptions);\n  isr?: number /* expiration */ | boolean | VercelISRConfig;\n  basicAuth?: Pick<BasicAuthOptions, \"password\" | \"username\" | \"realm\"> | false;\n\n  // Shortcuts\n  cors?: boolean;\n  swr?: boolean | number;\n  static?: boolean | number;\n}\n\nexport interface NitroRouteRules extends Omit<\n  NitroRouteConfig,\n  \"redirect\" | \"cors\" | \"swr\" | \"static\"\n> {\n  redirect?: { to: string; status: HTTPstatus };\n  proxy?: { to: string } & ProxyOptions;\n  [key: string]: any;\n}\n\nexport type MatchedRouteRule<K extends keyof NitroRouteRules = \"custom\"> = {\n  name: K;\n  options: Exclude<NitroRouteRules[K], false>;\n  route: string;\n  params?: Record<string, string>;\n  handler?: (opts: unknown) => Middleware;\n};\n\nexport type MatchedRouteRules = {\n  [K in keyof NitroRouteRules]: MatchedRouteRule<K>;\n};\n\n// https://vercel.com/docs/build-output-api/primitives#prerender-configuration-file\nexport interface VercelISRConfig {\n  /**\n   * (vercel)\n   * Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function.\n   * Setting the value to `false` (or `isr: true` route rule) means it will never expire.\n   */\n  expiration?: number | false;\n\n  /**\n   * (vercel)\n   * Group number of the asset.\n   * Prerender assets with the same group number will all be re-validated at the same time.\n   */\n  group?: number;\n\n  /**\n   * (vercel)\n   * List of query string parameter names that will be cached independently.\n   * - If an empty array, query values are not considered for caching.\n   * - If undefined each unique query value is cached independently\n   * - For wildcard `/**` route rules, `url` is always added.\n   */\n  allowQuery?: string[];\n\n  /**\n   * (vercel)\n   * When `true`, the query string will be present on the `request` argument passed to the invoked function. The `allowQuery` filter still applies.\n   */\n  passQuery?: boolean;\n\n  /**\n   * (vercel)\n   *\n   * When `true`, expose the response body regardless of status code including error status codes. (default `false`)\n   */\n  exposeErrBody?: boolean;\n}\n"
  },
  {
    "path": "src/types/runner.ts",
    "content": "export type {\n  FetchHandler,\n  RunnerMessageListener,\n  UpgradeHandler,\n  RunnerRPCHooks,\n  WorkerAddress,\n  WorkerHooks,\n  EnvRunner,\n} from \"env-runner\";\n"
  },
  {
    "path": "src/types/runtime/asset.ts",
    "content": "export interface PublicAsset {\n  type: string;\n  etag: string;\n  mtime: string;\n  path: string;\n  size: number;\n  encoding?: string;\n  data?: string;\n}\n\nexport interface AssetMeta {\n  type?: string;\n  etag?: string;\n  mtime?: string;\n}\n"
  },
  {
    "path": "src/types/runtime/cache.ts",
    "content": "import type { HTTPEvent } from \"h3\";\n\nexport type { CacheEntry, CacheOptions, ResponseCacheEntry } from \"ocache\";\n\nexport interface CachedEventHandlerOptions extends Omit<\n  import(\"ocache\").CachedEventHandlerOptions<HTTPEvent & import(\"ocache\").HTTPEvent>,\n  \"toResponse\" | \"createResponse\" | \"handleCacheHeaders\"\n> {}\n"
  },
  {
    "path": "src/types/runtime/index.ts",
    "content": "export * from \"./asset.ts\";\nexport * from \"./cache.ts\";\nexport * from \"./nitro.ts\";\nexport * from \"./task.ts\";\n"
  },
  {
    "path": "src/types/runtime/nitro.ts",
    "content": "import type { H3Core, HTTPEvent } from \"h3\";\nimport type { HookableCore } from \"hookable\";\nimport type { ServerRequest } from \"srvx\";\n\nexport interface NitroApp {\n  fetch: (req: Request) => Response | Promise<Response>;\n  h3?: H3Core;\n  hooks?: HookableCore<NitroRuntimeHooks>;\n  captureError?: CaptureError;\n}\n\nexport interface NitroAppPlugin {\n  (\n    nitro: NitroApp & {\n      hooks: NonNullable<NitroApp[\"hooks\"]>;\n    }\n  ): void;\n}\n\nexport interface NitroAsyncContext {\n  request: ServerRequest;\n}\n\nexport interface RenderResponse {\n  body: any;\n  status: number;\n  statusText: string;\n  headers: Record<string, string>;\n}\n\nexport type RenderHandler = (\n  event: HTTPEvent\n) => Partial<RenderResponse> | Promise<Partial<RenderResponse>>;\n\nexport interface RenderContext {\n  event: HTTPEvent;\n  render: RenderHandler;\n  response?: Partial<RenderResponse>;\n}\n\nexport interface CapturedErrorContext {\n  event?: HTTPEvent;\n  tags?: string[];\n}\n\nexport type CaptureError = (error: Error, context: CapturedErrorContext) => void;\n\nexport interface NitroRuntimeHooks {\n  close: () => void;\n  error: CaptureError;\n  request: (event: HTTPEvent) => void | Promise<void>;\n  response: (res: Response, event: HTTPEvent) => void | Promise<void>;\n}\n"
  },
  {
    "path": "src/types/runtime/task.ts",
    "content": "type MaybePromise<T> = T | Promise<T>;\n\n/** @experimental */\nexport interface TaskContext {}\n\n/** @experimental */\nexport interface TaskPayload {\n  [key: string]: unknown;\n}\n\n/** @experimental */\nexport interface TaskMeta {\n  name?: string;\n  description?: string;\n}\n\n/** @experimental */\nexport interface TaskEvent {\n  name: string;\n  payload: TaskPayload;\n  context: TaskContext;\n}\n\n/** @experimental */\nexport interface TaskResult<RT = unknown> {\n  result?: RT;\n}\n\n/** @experimental */\nexport interface Task<RT = unknown> {\n  meta?: TaskMeta;\n  run(event: TaskEvent): MaybePromise<{ result?: RT }>;\n}\n\n/** @experimental */\nexport interface TaskRunnerOptions {\n  cwd?: string;\n  buildDir?: string;\n}\n"
  },
  {
    "path": "src/types/srvx.ts",
    "content": "export type { ServerRequest } from \"srvx\";\n"
  },
  {
    "path": "src/utils/compress.ts",
    "content": "import { existsSync } from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport zlib from \"node:zlib\";\nimport { glob } from \"tinyglobby\";\nimport mime from \"mime\";\nimport type { Nitro } from \"nitro/types\";\nimport { resolve } from \"pathe\";\n\nconst EncodingMap = { gzip: \".gz\", br: \".br\", zstd: \".zst\" } as const;\n\nexport async function compressPublicAssets(nitro: Nitro) {\n  const publicFiles = await glob(\"**\", {\n    cwd: nitro.options.output.publicDir,\n    absolute: false,\n    dot: true,\n    ignore: [\"**/*.gz\", \"**/*.br\", \"**/*.zst\"],\n  });\n\n  await Promise.all(\n    publicFiles.map(async (fileName) => {\n      const compressPublicAssets = nitro.options.compressPublicAssets;\n      if (compressPublicAssets === false) {\n        return;\n      }\n\n      const {\n        gzip = false,\n        brotli = false,\n        zstd = false,\n      } = compressPublicAssets === true\n        ? { gzip: true, brotli: true, zstd: true }\n        : compressPublicAssets;\n      const zstdSupported = zlib.zstdCompress !== undefined;\n      const filePath = resolve(nitro.options.output.publicDir, fileName);\n\n      if (\n        (gzip && existsSync(filePath + EncodingMap.gzip)) ||\n        (brotli && existsSync(filePath + EncodingMap.br)) ||\n        (zstd && zstdSupported && existsSync(filePath + EncodingMap.zstd))\n      ) {\n        return;\n      }\n\n      const mimeType = mime.getType(fileName) || \"text/plain\";\n\n      const fileContents = await fsp.readFile(filePath);\n      if (\n        fileContents.length < 1024 ||\n        fileName.endsWith(\".map\") ||\n        !isCompressibleMime(mimeType)\n      ) {\n        return;\n      }\n\n      const encodings = [\n        gzip && (\"gzip\" as const),\n        brotli && (\"br\" as const),\n        zstd && zstdSupported && (\"zstd\" as const),\n      ].filter((v): v is keyof typeof EncodingMap => v !== false);\n\n      await Promise.all(\n        encodings.map(async (encoding) => {\n          const suffix = EncodingMap[encoding];\n          const compressedPath = filePath + suffix;\n          if (existsSync(compressedPath)) {\n            return;\n          }\n          const brotliOptions = {\n            [zlib.constants.BROTLI_PARAM_MODE]: isTextMime(mimeType)\n              ? zlib.constants.BROTLI_MODE_TEXT\n              : zlib.constants.BROTLI_MODE_GENERIC,\n            [zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_DEFAULT_QUALITY,\n            [zlib.constants.BROTLI_PARAM_SIZE_HINT]: fileContents.length,\n          };\n          const compressedBuff: Buffer = await new Promise((resolve, reject) => {\n            const cb = (error: Error | null, result: Buffer) =>\n              error ? reject(error) : resolve(result);\n            if (encoding === \"gzip\") {\n              zlib.gzip(fileContents, cb);\n            } else if (encoding === \"br\") {\n              zlib.brotliCompress(fileContents, brotliOptions, cb);\n            } else if (zstdSupported) {\n              zlib.zstdCompress(fileContents, cb);\n            }\n          });\n          await fsp.writeFile(compressedPath, compressedBuff);\n        })\n      );\n    })\n  );\n}\n\nfunction isTextMime(mimeType: string) {\n  return /text|javascript|json|xml/.test(mimeType);\n}\n\n// Reference list of compressible MIME types from AWS\n// https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types\nconst COMPRESSIBLE_MIMES_RE = new Set([\n  \"application/dash+xml\",\n  \"application/eot\",\n  \"application/font\",\n  \"application/font-sfnt\",\n  \"application/javascript\",\n  \"application/json\",\n  \"application/opentype\",\n  \"application/otf\",\n  \"application/pdf\",\n  \"application/pkcs7-mime\",\n  \"application/protobuf\",\n  \"application/rss+xml\",\n  \"application/truetype\",\n  \"application/ttf\",\n  \"application/vnd.apple.mpegurl\",\n  \"application/vnd.mapbox-vector-tile\",\n  \"application/vnd.ms-fontobject\",\n  \"application/wasm\",\n  \"application/xhtml+xml\",\n  \"application/xml\",\n  \"application/x-font-opentype\",\n  \"application/x-font-truetype\",\n  \"application/x-font-ttf\",\n  \"application/x-httpd-cgi\",\n  \"application/x-javascript\",\n  \"application/x-mpegurl\",\n  \"application/x-opentype\",\n  \"application/x-otf\",\n  \"application/x-perl\",\n  \"application/x-ttf\",\n  \"font/eot\",\n  \"font/opentype\",\n  \"font/otf\",\n  \"font/ttf\",\n  \"image/svg+xml\",\n  \"text/css\",\n  \"text/csv\",\n  \"text/html\",\n  \"text/javascript\",\n  \"text/js\",\n  \"text/plain\",\n  \"text/richtext\",\n  \"text/tab-separated-values\",\n  \"text/xml\",\n  \"text/x-component\",\n  \"text/x-java-source\",\n  \"text/x-script\",\n  \"vnd.apple.mpegurl\",\n]);\n\nfunction isCompressibleMime(mimeType: string) {\n  return COMPRESSIBLE_MIMES_RE.has(mimeType);\n}\n"
  },
  {
    "path": "src/utils/dep.ts",
    "content": "import { consola } from \"consola\";\nimport { resolveModulePath } from \"exsolve\";\nimport { isCI, isTest } from \"std-env\";\n\nexport async function importDep<T>(\n  opts: {\n    id: string;\n    dir: string;\n    reason: string;\n  },\n  _retry?: boolean\n): Promise<T> {\n  const resolved = resolveModulePath(opts.id, {\n    from: [opts.dir, import.meta.url],\n    cache: _retry ? false : true,\n    try: true,\n  });\n\n  if (resolved) {\n    return (await import(resolved)) as Promise<T>;\n  }\n\n  let shouldInstall: boolean | undefined;\n  if (_retry || isTest) {\n    shouldInstall = false; // Do not install dependencies in test mode\n  } else if (isCI) {\n    consola.info(\n      `\\`${opts.id}\\` is required for ${opts.reason}. Installing automatically in CI environment...`\n    );\n    shouldInstall = true; // Auto install in CI environments\n  } else {\n    shouldInstall = await consola.prompt(\n      `\\`${opts.id}\\` is required for ${opts.reason}, but it is not installed. Would you like to install it?`,\n      { type: \"confirm\", default: true, cancel: \"undefined\" }\n    );\n  }\n\n  if (!shouldInstall) {\n    throw new Error(\n      `\\`${opts.id}\\` is not installed. Please add it to your dependencies for ${opts.reason}.`\n    );\n  }\n\n  const start = Date.now();\n  consola.start(`Installing \\`${opts.id}\\` in \\`${opts.dir}\\`...`);\n  const { addDevDependency } = await import(\"nypm\");\n  await addDevDependency(opts.id, { cwd: opts.dir });\n  consola.success(`Installed \\`${opts.id}\\` in ${opts.dir} (${Date.now() - start}ms).`);\n\n  return importDep<T>(opts, true);\n}\n"
  },
  {
    "path": "src/utils/fs-tree.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { colors } from \"consola/utils\";\nimport { glob } from \"tinyglobby\";\nimport { gzipSize } from \"gzip-size\";\nimport { dirname, relative, resolve } from \"pathe\";\nimport prettyBytes from \"pretty-bytes\";\nimport { isTest } from \"std-env\";\nimport { runParallel } from \"./parallel.ts\";\n\nexport async function generateFSTree(dir: string, options: { compressedSizes?: boolean } = {}) {\n  if (isTest) {\n    return;\n  }\n\n  const files = await glob(\"**/*.*\", { cwd: dir, ignore: [\"*.map\"] });\n\n  const items: { file: string; path: string; size: number; gzip: number }[] = [];\n\n  await runParallel(\n    new Set(files),\n    async (file) => {\n      const path = resolve(dir, file);\n      const src = await fsp.readFile(path);\n      const size = src.byteLength;\n      const gzip = options.compressedSizes ? await gzipSize(src) : 0;\n      items.push({ file, path, size, gzip });\n    },\n    { concurrency: 10 }\n  );\n\n  items.sort((a, b) => a.path.localeCompare(b.path));\n\n  let totalSize = 0;\n  let totalGzip = 0;\n\n  let totalNodeModulesSize = 0;\n  let totalNodeModulesGzip = 0;\n\n  let treeText = \"\";\n\n  for (const [index, item] of items.entries()) {\n    let dir = dirname(item.file);\n    if (dir === \".\") {\n      dir = \"\";\n    }\n    const rpath = relative(process.cwd(), item.path);\n    const treeChar = index === items.length - 1 ? \"└─\" : \"├─\";\n\n    const isNodeModules = item.file.includes(\"node_modules\");\n\n    if (isNodeModules) {\n      totalNodeModulesSize += item.size;\n      totalNodeModulesGzip += item.gzip;\n      continue;\n    }\n\n    treeText += colors.gray(`  ${treeChar} ${rpath} (${prettyBytes(item.size)})`);\n    if (options.compressedSizes) {\n      treeText += colors.gray(` (${prettyBytes(item.gzip)} gzip)`);\n    }\n    treeText += \"\\n\";\n    totalSize += item.size;\n    totalGzip += item.gzip;\n  }\n\n  treeText += `${colors.cyan(\"Σ Total size:\")} ${prettyBytes(totalSize + totalNodeModulesSize)}`;\n  if (options.compressedSizes) {\n    treeText += ` (${prettyBytes(totalGzip + totalNodeModulesGzip)} gzip)`;\n  }\n  treeText += \"\\n\";\n\n  return treeText;\n}\n"
  },
  {
    "path": "src/utils/fs.ts",
    "content": "import type { Nitro } from \"nitro/types\";\nimport { stat, mkdir, writeFile as fspWriteFile } from \"node:fs/promises\";\nimport { dirname } from \"pathe\";\nimport consola from \"consola\";\nimport { colors } from \"consola/utils\";\nimport { getProperty } from \"dot-prop\";\nimport { relative, resolve } from \"pathe\";\n\nexport function prettyPath(p: string, highlight = true) {\n  p = relative(process.cwd(), p);\n  return highlight ? colors.cyan(p) : p;\n}\n\nexport function resolveNitroPath(\n  path: string,\n  nitroOptions: Nitro[\"options\"],\n  base?: string\n): string {\n  if (typeof path !== \"string\") {\n    throw new TypeError(\"Invalid path: \" + path);\n  }\n\n  // TODO: Skip if no template used\n  path = _compilePathTemplate(path)(nitroOptions);\n  for (const base in nitroOptions.alias) {\n    if (path.startsWith(base)) {\n      path = nitroOptions.alias[base] + path.slice(base.length);\n    }\n  }\n\n  // eslint-disable-next-line no-control-regex\n  if (/^[#\\u0000]/.test(path)) {\n    return path;\n  }\n\n  return resolve(base || nitroOptions.rootDir, path);\n}\n\nfunction _compilePathTemplate(contents: string) {\n  return (params: Record<string, any>) =>\n    contents.replace(/{{ ?([\\w.]+) ?}}/g, (_, match) => {\n      const val = getProperty<Record<string, string>, string>(params, match);\n      if (!val) {\n        consola.warn(`cannot resolve template param '${match}' in ${contents.slice(0, 20)}`);\n      }\n      return val || `${match}`;\n    });\n}\n\nexport async function writeFile(file: string, contents: Buffer | string, log = false) {\n  await mkdir(dirname(file), { recursive: true });\n  await fspWriteFile(file, contents, typeof contents === \"string\" ? \"utf8\" : undefined);\n  if (log) {\n    consola.info(\"Generated\", prettyPath(file));\n  }\n}\n\nexport async function isDirectory(path: string) {\n  try {\n    return (await stat(path)).isDirectory();\n  } catch {\n    return false;\n  }\n}\n"
  },
  {
    "path": "src/utils/parallel.ts",
    "content": "export async function runParallel<T>(\n  inputs: Set<T>,\n  cb: (input: T) => unknown | Promise<unknown>,\n  opts: { concurrency: number; interval?: number }\n): Promise<{ errors: unknown[] }> {\n  const errors: unknown[] = [];\n  const tasks = new Set<Promise<unknown>>();\n\n  function queueNext(): undefined | Promise<unknown> {\n    const route = inputs.values().next().value;\n    if (!route) {\n      return;\n    }\n\n    inputs.delete(route);\n    const task = (\n      opts.interval\n        ? new Promise((resolve) => setTimeout(resolve, opts.interval))\n        : Promise.resolve()\n    )\n      .then(() => cb(route))\n      .catch((error) => {\n        console.error(error);\n        errors.push(error);\n      });\n\n    tasks.add(task);\n    return task.then(() => {\n      tasks.delete(task);\n      if (inputs.size > 0) {\n        return refillQueue();\n      }\n    });\n  }\n\n  function refillQueue(): Promise<unknown> {\n    const workers = Math.min(opts.concurrency - tasks.size, inputs.size);\n    return Promise.all(Array.from({ length: workers }, () => queueNext()));\n  }\n\n  await refillQueue();\n\n  return { errors };\n}\n"
  },
  {
    "path": "src/utils/regex.ts",
    "content": "import { isWindows } from \"std-env\";\n\nexport function escapeRegExp(string: string): string {\n  return string.replace(/[-\\\\^$*+?.()|[\\]{}]/g, String.raw`\\$&`);\n}\n\nexport function pathRegExp(string: string): string {\n  if (isWindows) {\n    string = string.replace(/\\\\/g, \"/\");\n  }\n  let escaped = escapeRegExp(string);\n  if (isWindows) {\n    escaped = escaped.replace(/\\//g, String.raw`[/\\\\]`);\n  }\n  return escaped;\n}\n\nexport function toPathRegExp(input: string | RegExp): RegExp {\n  if (input instanceof RegExp) {\n    return input;\n  }\n  if (typeof input === \"string\") {\n    return new RegExp(pathRegExp(input));\n  }\n  throw new TypeError(\"Expected a string or RegExp\", { cause: input });\n}\n"
  },
  {
    "path": "src/vite.ts",
    "content": "export { nitro } from \"./build/vite/plugin.ts\";\n\nexport type { NitroPluginConfig, ServiceConfig } from \"./build/vite/types.ts\";\n"
  },
  {
    "path": "test/examples.test.ts",
    "content": "import { join } from \"node:path\";\nimport { readdir } from \"node:fs/promises\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { toRequest } from \"h3\";\nimport { describe, test, expect, beforeAll, afterAll } from \"vitest\";\n\nimport type { ViteDevServer } from \"vite\";\n\nconst examplesDir = fileURLToPath(new URL(\"../examples\", import.meta.url));\n\nconst { createServer, createBuilder, rolldownVersion } = (await import(\n  process.env.NITRO_VITE_PKG || \"vite\"\n)) as typeof import(\"vite\");\n\nconst isRolldown = !!rolldownVersion;\n\nconst skip = new Set<string>([\n  \"websocket\",\n  ...(isRolldown\n    ? [\n        // TODO: Cannot read properties of null (reading 'use')\n        \"vite-rsc\",\n      ]\n    : [\n        \"vite-rsc\",\n        // No tsConfigPaths support in rollup\n        \"import-alias\",\n      ]),\n]);\n\nconst skipDev = new Set<string>([\"auto-imports\", \"cached-handler\"]);\n\nconst skipProd = new Set<string>(isRolldown ? [] : []);\n\nfor (const example of await readdir(examplesDir)) {\n  if (example.startsWith(\"_\")) continue;\n  setupTest(example);\n}\n\nfunction setupTest(name: string) {\n  const rootDir = join(examplesDir, name);\n\n  describe.skipIf(skip.has(name))(name, () => {\n    type TestContext = {\n      fetch: typeof globalThis.fetch;\n    };\n\n    function registerTests(ctx: TestContext, mode: string) {\n      test(`${name} (${mode})`, async () => {\n        const res = await ctx.fetch(\"/\");\n        const expectedStatus = name === \"custom-error-handler\" ? 500 : 200;\n        expect(res.status, res.statusText).toBe(expectedStatus);\n      });\n    }\n\n    describe.skipIf(skipDev.has(name))(`${name} (dev)`, () => {\n      let server: ViteDevServer;\n      const context: TestContext = {} as any;\n\n      beforeAll(async () => {\n        process.chdir(rootDir);\n        server = await createServer({ root: rootDir });\n        await server.listen(\"0\" as unknown as number);\n        const addr = server.httpServer?.address() as {\n          port: number;\n          address: string;\n          family: string;\n        };\n        const baseURL = `http://${addr.family === \"IPv6\" ? `[${addr.address}]` : addr.address}:${addr.port}`;\n        context.fetch = (url, opts) => fetch(baseURL + url, opts);\n      }, 30_000);\n\n      afterAll(async () => {\n        await server?.close();\n      });\n\n      registerTests(context, \"dev\");\n    });\n\n    describe.skipIf(skipProd.has(name))(`${name} (prod)`, () => {\n      const context: TestContext = {} as any;\n\n      beforeAll(async () => {\n        process.chdir(rootDir);\n\n        process.env.NITRO_PRESET = \"standard\";\n        const builder = await createBuilder({ logLevel: \"warn\" });\n        await builder.buildApp();\n\n        delete globalThis.__nitro__;\n\n        const { default: entryMod } = await import(\n          pathToFileURL(join(rootDir, \".output/server/index.mjs\")).href\n        );\n\n        delete (globalThis as any).document; // Set by nano-jsx!\n\n        expect(entryMod?.fetch).toBeInstanceOf(Function);\n        context.fetch = (input, init) => entryMod.fetch(toRequest(input, init));\n      }, 30_000);\n\n      registerTests(context, \"prod\");\n    });\n  });\n}\n"
  },
  {
    "path": "test/fixture/.env",
    "content": "APP_DOMAIN=test.com\nNITRO_DYNAMIC=from-env\n"
  },
  {
    "path": "test/fixture/.gitignore",
    "content": "!.env\n!node_modules/@fixture\nvercel.json\n"
  },
  {
    "path": "test/fixture/error.ts",
    "content": "import { defineErrorHandler } from \"nitro\";\n\nexport default defineErrorHandler(async (error, event, { defaultHandler }) => {\n  if (event.req.url.includes(\"?json\")) {\n    const res = await defaultHandler(error, event, { json: true });\n    return Response.json({ json: res.body });\n  }\n});\n"
  },
  {
    "path": "test/fixture/exports.cloudflare.ts",
    "content": "export function myScheduled() {\n  console.log(\"scheduled!\");\n}\n"
  },
  {
    "path": "test/fixture/nitro.config.ts",
    "content": "import { defineConfig } from \"nitro\";\n\nimport { dirname, resolve } from \"node:path\";\nimport { existsSync } from \"node:fs\";\n\nexport default defineConfig({\n  compressPublicAssets: true,\n  compatibilityDate: \"latest\",\n  serverDir: \"server\",\n  builder: (process.env.NITRO_BUILDER as any) || \"rolldown\",\n  // @ts-expect-error\n  __vitePkg__: process.env.NITRO_VITE_PKG,\n  framework: { name: \"nitro\", version: \"3.x\" },\n  imports: {\n    presets: [\n      {\n        // TODO: move this to built-in preset\n        from: \"scule\",\n        imports: [\"camelCase\", \"pascalCase\", \"kebabCase\"],\n      },\n    ],\n  },\n  sourcemap: true,\n  rollupConfig: {\n    output: {\n      sourcemapPathTransform: (relativeSourcePath, sourcemapPath) => {\n        const sourcemapDir = dirname(sourcemapPath);\n        const sourcePath = resolve(sourcemapDir, relativeSourcePath);\n        return existsSync(sourcePath) ? sourcePath : relativeSourcePath;\n      },\n    },\n  },\n  virtual: {\n    \"#virtual-route\": () => `export default () => new Response(\"Hello from virtual entry!\")`,\n  },\n  handlers: [\n    {\n      route: \"/api/test/*/foo\",\n      handler: \"./server/routes/api/hello.ts\",\n      method: \"GET\",\n    },\n    {\n      route: \"/api/hello2\",\n      handler: \"./server/routes/api/hello.ts\",\n      middleware: true,\n    },\n    {\n      route: \"/virtual\",\n      handler: \"#virtual-route\",\n    },\n  ],\n  devProxy: {\n    \"/proxy/example\": {\n      target: \"https://icanhazip.com\",\n      changeOrigin: true,\n      ignorePath: true,\n    },\n  },\n  traceDeps: [\"@fixture\"],\n  serverAssets: [\n    {\n      baseName: \"files\",\n      dir: \"server/files\",\n    },\n  ],\n  ignore: [\"routes/api/**/_*\", \"middleware/_ignored.ts\", \"routes/_*.ts\", \"**/_*.txt\"],\n  runtimeConfig: {\n    dynamic: \"initial\",\n    url: \"https://{{APP_DOMAIN}}\",\n  },\n  publicAssets: [\n    {\n      baseURL: \"build\",\n      dir: \"public/build\",\n      maxAge: 3600,\n    },\n  ],\n  tasks: {\n    \"db:migrate\": { description: \"Migrate database\" },\n    \"db:seed\": { description: \"Seed database\" },\n  },\n  errorHandler: \"error.ts\",\n  routeRules: {\n    \"/api/param/prerender4\": { prerender: true },\n    \"/api/param/prerender2\": { prerender: false },\n    \"/rules/headers\": { headers: { \"cache-control\": \"s-maxage=60\" } },\n    \"/rules/cors\": {\n      cors: true,\n      headers: { \"access-control-allow-methods\": \"GET\" },\n    },\n    \"/rules/dynamic\": { cache: false, isr: false },\n    \"/rules/redirect\": { redirect: \"/base\" },\n    \"/rules/isr/**\": { isr: { allowQuery: [\"q\"] } },\n    \"/rules/isr-ttl/**\": { isr: 60 },\n    \"/rules/swr/**\": { swr: true },\n    \"/rules/swr-ttl/**\": { swr: 60 },\n    \"/rules/redirect/obj\": {\n      redirect: { to: \"https://nitro.build/\", status: 308 },\n    },\n    \"/rules/redirect/wildcard/**\": { redirect: \"https://nitro.build/**\" },\n    \"/rules/nested/**\": { redirect: \"/base\", headers: { \"x-test\": \"test\" } },\n    \"/rules/nested/override\": { redirect: { to: \"/other\" } },\n    \"/rules/_/noncached/cached\": { swr: true },\n    \"/rules/_/noncached/**\": { swr: false, cache: false, isr: false },\n    \"/rules/_/cached/noncached\": { cache: false, swr: false, isr: false },\n    \"/rules/_/cached/**\": { swr: true },\n    \"/api/proxy/**\": { proxy: \"/api/echo\" },\n    \"/cdn/**\": { proxy: \"https://cdn.jsdelivr.net/**\" },\n    \"/rules/basic-auth/**\": {\n      basicAuth: { username: \"admin\", password: \"secret\", realm: \"Secure Area\" },\n    },\n    \"/rules/basic-auth/no-auth/**\": { basicAuth: false },\n    \"**\": { headers: { \"x-test\": \"test\" } },\n  },\n  prerender: {\n    crawlLinks: true,\n    ignore: [\n      // '/api/param/'\n    ],\n    routes: [\"/prerender\", \"/prerender-custom.html\", \"/404\"],\n  },\n  experimental: {\n    openAPI: true,\n    asyncContext: true,\n    envExpansion: true,\n    database: true,\n    tasks: true,\n  },\n  scheduledTasks: {\n    \"* * * * *\": \"test\",\n  },\n  cloudflare: {\n    pages: {\n      routes: {\n        include: [\"/*\"],\n        exclude: [\"/blog/static/*\", \"/cf-pages-exclude/*\"],\n      },\n    },\n    wrangler: {\n      compatibility_date: \"2024-01-01\",\n    },\n  },\n  typescript: {\n    generateRuntimeConfigTypes: true,\n    generateTsConfig: true,\n  },\n  openAPI: {\n    production: \"prerender\",\n    meta: {\n      title: \"Nitro Test Fixture\",\n      description: \"Nitro Test Fixture API\",\n      version: \"2.0\",\n    },\n  },\n});\n"
  },
  {
    "path": "test/fixture/package.json",
    "content": "{\n  \"name\": \"nitro-test-fixture\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nitro build\",\n    \"preview\": \"nitro preview\",\n    \"dev\": \"nitro dev\"\n  },\n  \"devDependencies\": {\n    \"mono-jsx\": \"^0.8.2\",\n    \"nitro\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "test/fixture/public/_ignored.txt",
    "content": "This file should be ignored!\n"
  },
  {
    "path": "test/fixture/public/_unignored.txt",
    "content": "This file should not be ignored!\n"
  },
  {
    "path": "test/fixture/public/build/test.txt",
    "content": "Works!\n"
  },
  {
    "path": "test/fixture/public/cf-pages-exclude/not-in-routes-json.txt",
    "content": "This file shouldn't be under \"exclude\" in the _routes.json outputted by Cloudflare Pages builds.\nIt's covered by the \"/cf-pages-exclude/*\" wildcard.\n"
  },
  {
    "path": "test/fixture/public/foo.css",
    "content": ""
  },
  {
    "path": "test/fixture/public/foo.js",
    "content": "const hello = \"world\";\n"
  },
  {
    "path": "test/fixture/server/assets/test.json",
    "content": "{\n  \"foo\": \"bar\"\n}\n"
  },
  {
    "path": "test/fixture/server/assets/test.md",
    "content": "# Hello world\n\nUse `process.env.NODE_ENV` to ...\n"
  },
  {
    "path": "test/fixture/server/files/index.html",
    "content": "<h1>nitro is amazing!</h1>\n"
  },
  {
    "path": "test/fixture/server/files/sql.sql",
    "content": "--\n"
  },
  {
    "path": "test/fixture/server/files/sqlts.sql.ts",
    "content": "export default \"--\\n\";\n"
  },
  {
    "path": "test/fixture/server/files/test.txt",
    "content": "this is an asset from a text file from nitro\n"
  },
  {
    "path": "test/fixture/server/middleware/_ignored.ts",
    "content": "import { HTTPError } from \"nitro/h3\";\n\nexport default () => {\n  throw new HTTPError(\"This file should be ignored!\");\n};\n"
  },
  {
    "path": "test/fixture/server/plugins/errors.ts",
    "content": "import { definePlugin } from \"nitro\";\n\nexport const allErrors: { error: Error; context: any }[] = [];\n\nexport default definePlugin((app) => {\n  app.hooks.hook(\"error\", (error, context) => {\n    allErrors.push({ error, context });\n  });\n});\n"
  },
  {
    "path": "test/fixture/server/plugins/vary.ts",
    "content": "import { definePlugin } from \"nitro\";\n\nexport default definePlugin((app) => {\n  app.hooks.hook(\"response\", (res, event) => {\n    const { pathname } = new URL(event.req.url);\n    if (pathname.endsWith(\".css\") || pathname.endsWith(\".js\")) {\n      res.headers.append(\"Vary\", \"Origin\");\n    }\n  });\n});\n"
  },
  {
    "path": "test/fixture/server/routes/(route-group)/route-group.ts",
    "content": "export default () => {\n  return \"Hi from inside group\";\n};\n"
  },
  {
    "path": "test/fixture/server/routes/500.ts",
    "content": "import { HTTPError } from \"nitro/h3\";\n\nexport default () => {\n  throw new HTTPError({ status: 500, statusText: \"Test Error\" });\n};\n"
  },
  {
    "path": "test/fixture/server/routes/api/_ignored.ts",
    "content": "import { HTTPError } from \"nitro/h3\";\n\nexport default () => {\n  throw new HTTPError(\"This file should be ignored!\");\n};\n"
  },
  {
    "path": "test/fixture/server/routes/api/cached.ts",
    "content": "import { defineCachedHandler } from \"nitro/cache\";\n\nexport default defineCachedHandler(\n  (event) => {\n    return {\n      timestamp: Date.now(),\n      eventContextCache: event.context.cache,\n    };\n  },\n  { swr: true, maxAge: 60 }\n);\n"
  },
  {
    "path": "test/fixture/server/routes/api/db.ts",
    "content": "import { useDatabase } from \"nitro/database\";\n\nexport default async () => {\n  const db = useDatabase();\n\n  // Create users table\n  await db.sql`DROP TABLE IF EXISTS users`;\n  await db.sql`CREATE TABLE IF NOT EXISTS users (\"id\" TEXT PRIMARY KEY, \"firstName\" TEXT, \"lastName\" TEXT, \"email\" TEXT)`;\n\n  // Add a new user\n  const userId = \"1001\";\n  await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;\n\n  // Query for users\n  const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;\n\n  return {\n    rows,\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/api/echo.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  return {\n    url: event.path,\n    method: event.method,\n    headers: Object.fromEntries(event.headers.entries()),\n  };\n});\n"
  },
  {
    "path": "test/fixture/server/routes/api/headers.ts",
    "content": "import { defineHandler, setCookie } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  event.res.headers.set(\"x-foo\", \"bar\");\n  event.res.headers.append(\"x-array\", \"foo\");\n  event.res.headers.append(\"x-array\", \"bar\");\n\n  // setHeader(event, \"Set-Cookie\", \"foo=bar, bar=baz\");\n  event.res.headers.append(\"Set-Cookie\", \"foo=bar\");\n  event.res.headers.append(\"Set-Cookie\", \"bar=baz\");\n  setCookie(event, \"test\", \"value\");\n  setCookie(event, \"test2\", \"value\");\n\n  return \"headers sent\";\n});\n"
  },
  {
    "path": "test/fixture/server/routes/api/hello.ts",
    "content": "export default () => ({ message: \"Hello API\" });\n"
  },
  {
    "path": "test/fixture/server/routes/api/hey/index.get.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  event.res.headers.set(\"Content-Type\", \"text/html\");\n  return \"Hey API\";\n});\n"
  },
  {
    "path": "test/fixture/server/routes/api/kebab.ts",
    "content": "import { kebabCase } from \"scule\";\n\nexport default () => kebabCase(\"HelloWorld\");\n"
  },
  {
    "path": "test/fixture/server/routes/api/meta/test.ts",
    "content": "import { defineRouteMeta } from \"nitro\";\n\ndefineRouteMeta({\n  openAPI: {\n    tags: [\"test\"],\n    description: \"Test route description\",\n    parameters: [\n      { in: \"query\", name: \"test\", required: true },\n      {\n        in: \"query\",\n        name: \"val\",\n        schema: { type: \"integer\", enum: [0, 1] },\n      },\n    ],\n    responses: {\n      200: {\n        description: \"result\",\n        content: {\n          \"application/json\": { schema: { $ref: \"#/components/schemas/Test\" } },\n        },\n      },\n    },\n    $global: {\n      components: {\n        schemas: {\n          Test: {\n            type: \"object\",\n            properties: {\n              status: {\n                type: \"string\",\n                enum: [\"OK\", \"ERROR\"],\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n});\n\nexport default () => {\n  return {\n    status: \"OK\",\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/api/methods/foo.get.get.ts",
    "content": "export default () => \"foo.get\";\n"
  },
  {
    "path": "test/fixture/server/routes/api/methods/get.ts",
    "content": "export default () => \"get\";\n"
  },
  {
    "path": "test/fixture/server/routes/api/param/[test-id].ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  event.res.headers.set(\"Content-Type\", \"text/plain; custom\");\n  return event.context.params![\"test-id\"];\n});\n"
  },
  {
    "path": "test/fixture/server/routes/api/storage/item.get.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\nimport { useStorage } from \"nitro/storage\";\n\nexport default defineHandler(async (event) => {\n  const base = event.url.searchParams.get(\"base\") || \"\";\n  const key = event.url.searchParams.get(\"key\") || \"\";\n  const storage = useStorage(`test:${base}`);\n\n  if (!key || key.endsWith(\":\")) {\n    return await storage.getKeys();\n  }\n\n  const value = await storage.getItem(key);\n  return value;\n});\n"
  },
  {
    "path": "test/fixture/server/routes/api/storage/item.put.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\nimport { useStorage } from \"nitro/storage\";\n\nexport default defineHandler(async (event) => {\n  const base = event.url.searchParams.get(\"base\") || \"\";\n  const key = event.url.searchParams.get(\"key\") || \"\";\n  const storage = useStorage(`test:${base}`);\n  const value = await event.req.text();\n  await storage.setItem(key, value);\n  return value;\n});\n"
  },
  {
    "path": "test/fixture/server/routes/api/upload.post.ts",
    "content": "export default () => {\n  return \"uploaded!\";\n};\n"
  },
  {
    "path": "test/fixture/server/routes/api/wildcard/[...param].ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  return event.context.params!.param as string;\n});\n"
  },
  {
    "path": "test/fixture/server/routes/assets/[id].ts",
    "content": "import { defineHandler, HTTPError } from \"nitro/h3\";\nimport { useStorage } from \"nitro/storage\";\n\nexport default defineHandler(async (event) => {\n  const serverAssets = useStorage(\"assets/server\");\n\n  const id = event.context.params!.id;\n\n  if (!(await serverAssets.hasItem(id))) {\n    throw new HTTPError({ message: `Asset ${id} not found`, status: 404 });\n  }\n\n  const meta = (await serverAssets.getMeta(event.context.params!.id)) as unknown as {\n    type: string;\n    etag: string;\n    mtime: string;\n  };\n\n  if (meta.type) {\n    event.res.headers.set(\"content-type\", meta.type);\n  }\n\n  if (meta.etag) {\n    event.res.headers.set(\"etag\", meta.etag);\n  }\n\n  if (meta.mtime) {\n    event.res.headers.set(\"last-modified\", meta.mtime);\n  }\n\n  return serverAssets.getItemRaw(event.context.params!.id);\n});\n"
  },
  {
    "path": "test/fixture/server/routes/assets/all.ts",
    "content": "import { useStorage } from \"nitro/storage\";\n\nexport default async () => {\n  const serverAssets = useStorage(\"assets/server\");\n\n  const keys = await serverAssets.getKeys();\n  const items = await Promise.all(\n    keys.map(async (key) => {\n      return {\n        key,\n        meta: await serverAssets.getMeta(key),\n        data: await serverAssets.getItem(key).then((r) =>\n          // prettier-ignore\n          typeof r === \"string\" ? r.slice(0, 32) : (isPureObject(r) ? r : `<data>`)\n        ),\n      };\n    })\n  );\n\n  return items;\n};\n\nfunction isPureObject(value: unknown): boolean {\n  return value !== null && typeof value === \"object\" && value.constructor === Object;\n}\n"
  },
  {
    "path": "test/fixture/server/routes/assets/md.ts",
    "content": "export default async () => {\n  const md = await import(\"raw:../../assets/test.md\" as string).then((r) => r.default);\n  return md;\n};\n"
  },
  {
    "path": "test/fixture/server/routes/config.ts",
    "content": "import { useRuntimeConfig } from \"nitro/runtime-config\";\n\nconst sharedRuntimeConfig = useRuntimeConfig();\n\nexport default () => {\n  const runtimeConfig = useRuntimeConfig();\n\n  return {\n    runtimeConfig,\n    sharedRuntimeConfig,\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/context.ts",
    "content": "import { defineEventHandler } from \"nitro/h3\";\nimport { useRequest } from \"nitro/context\";\n\nexport default defineEventHandler(async () => {\n  await Promise.resolve(setTimeout(() => {}, 10));\n  return await useTest();\n});\n\nfunction useTest() {\n  const url = new URL(useRequest().url);\n  return {\n    context: {\n      path: url.pathname + url.search,\n    },\n  };\n}\n"
  },
  {
    "path": "test/fixture/server/routes/env/index.dev.ts",
    "content": "export default () => \"dev env\";\n"
  },
  {
    "path": "test/fixture/server/routes/env/index.get.prod.ts",
    "content": "export default () => \"prod env\";\n"
  },
  {
    "path": "test/fixture/server/routes/errors/captured.ts",
    "content": "import { allErrors } from \"../../plugins/errors.ts\";\n\nexport default () => {\n  return {\n    allErrors: allErrors.map((entry) => ({\n      message: entry.error.message,\n    })),\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/errors/stack.ts",
    "content": "export default async () => {\n  return {\n    stack: new Error(\"testing error\").stack!.replace(/\\\\/g, \"/\"),\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/errors/throw.ts",
    "content": "import { H3Event, HTTPError } from \"nitro/h3\";\n\nexport default ({ url }: H3Event) => {\n  const unhandled = url.searchParams.has(\"unhandled\");\n  const shouldThrow = url.searchParams.get(\"action\") === \"throw\";\n\n  const error = unhandled\n    ? new Error(\"Unhandled error\")\n    : new HTTPError({\n        status: 503,\n        statusText: \"Custom Status Text\",\n        message: \"Handled error\",\n        headers: { \"x-custom-error\": \"custom-value\" },\n        data: { custom: \"data\" },\n        body: { custom: \"body\" },\n      });\n\n  if (shouldThrow) {\n    throw error;\n  }\n\n  return error;\n};\n"
  },
  {
    "path": "test/fixture/server/routes/fetch.ts",
    "content": "import { serverFetch as runtimeServerFetch, fetch as runtimeFetch, useNitroApp } from \"nitro/app\";\n\nimport { serverFetch as nitroServerFetch, fetch as nitroFetch } from \"nitro\";\n\nexport default async () => {\n  const nitroApp = useNitroApp();\n  return {\n    \"nitroApp.fetch\": await Promise.resolve(\n      nitroApp.fetch(new Request(new URL(\"/api/hello\", \"http://localhost\")))\n    ).then((res) => res.json()),\n    \"nitro/runtime.serverFetch\": await runtimeServerFetch(\"/api/hello\").then((res) => res.json()),\n    \"nitro/runtime.fetch\": await runtimeFetch(\"/api/hello\").then((res) => res.json()),\n    \"nitro/serverFetch\": await nitroServerFetch(\"/api/hello\").then((res) => res.json()),\n    \"nitro/fetch\": await nitroFetch(\"/api/hello\").then((res) => res.json()),\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/file.ts",
    "content": "import { defineHandler, getQuery } from \"nitro/h3\";\n\nimport { useStorage } from \"nitro/storage\";\n\nexport default defineHandler(async (event) => {\n  const query = getQuery(event);\n  const filename = query?.filename || \"index.html\";\n  const serverAsset = await useStorage().getItem(`assets/files/${filename}`);\n  return serverAsset;\n});\n"
  },
  {
    "path": "test/fixture/server/routes/icon.png.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  event.res.headers.set(\"Content-Type\", \"image/png\");\n  return Buffer.from(_base64ToArray(_getLogoBase64()));\n});\n\nfunction _getLogoBase64() {\n  return \"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAT9JREFUOE+t081KAlEUwPH/nRkn0pmgZWQgFLTpBYqQVkFUmgTRNnqKkFrZop7Blm4KQq02rVqYr1AILaKPZYIzGY46ExdRNMWP6u4ul/O759x7jggli0fgxQGd0ZYD4liEkh+VXwQ3r3Ik4DV3igBVQNXtnYomQB65rQjoALbndE7DAfZvbe5eq11KJmKSeqxwXnBaZ13ASThAyfHYTJd4sztTGQrYWxjjueQybSjsXFs4bcbQwO6NTSZqkn+vcZgvt9IdGthIW8xPqlxGTOK5MumnRs0jATIgNquTWPYTy1oUivXRAYkklvwsTmlEsxapNWPwL8hHlCU0l67CxbrJi+0yYyqkHgZ8409AQkFD4WprAsMniN9/9u+DXoBEVoI+zlYNDnJ9AE0Bn4Cveu9WHtcabV5r643/GKa/jfM3OT68lZwxK8oAAAAASUVORK5CYII=\";\n}\n\nfunction _base64ToArray(base64: string) {\n  const str = atob(base64);\n  const bytes = new Uint8Array(str.length);\n  for (let i = 0; i < str.length; i++) {\n    bytes[i] = str.charCodeAt(i);\n  }\n  return bytes;\n}\n"
  },
  {
    "path": "test/fixture/server/routes/imports.ts",
    "content": "import { testBarUtil } from \"../utils/foo/bar/test.ts\";\nimport { testFooUtil } from \"../utils/foo/test.ts\";\nimport { testUtil } from \"../utils/test.ts\";\n\nexport default () => {\n  return {\n    testUtil: testUtil(),\n    testNestedUtil: testFooUtil() + testBarUtil(),\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/json-string.ts",
    "content": "export default () => {\n  return '{\"foo\":\"bar\"}';\n};\n"
  },
  {
    "path": "test/fixture/server/routes/jsx.tsx",
    "content": "export default () => (\n  <html>\n    <h1 class=\"test\">Hello JSX!</h1>\n  </html>\n);\n"
  },
  {
    "path": "test/fixture/server/routes/modules.ts",
    "content": "// @ts-ignore\nimport depA from \"@fixture/nitro-dep-a\";\n// @ts-ignore\nimport depB from \"@fixture/nitro-dep-b\";\n// @ts-ignore\nimport depLib from \"@fixture/nitro-lib\";\n// @ts-ignore\nimport subpathLib from \"@fixture/nitro-lib/subpath\";\n// @ts-ignore\nimport extraUtils from \"@fixture/nitro-utils/extra\";\n\nexport default () => {\n  return {\n    depA, // expected to all be 1.0.0\n    depB, // expected to all be 2.0.1\n    depLib, // expected to all be 2.0.0\n    subpathLib, // expected to 2.0.0\n    extraUtils,\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/node-compat.ts",
    "content": "import nodeAsyncHooks from \"node:async_hooks\";\nimport nodeCrypto from \"node:crypto\";\nimport nodeTLS from \"node:tls\";\n\nconst nodeCompatTests = {\n  globals: {\n    // eslint-disable-next-line unicorn/prefer-global-this\n    global: () => globalThis.global === global,\n    // eslint-disable-next-line unicorn/prefer-global-this\n    Buffer: () => Buffer && globalThis.Buffer && global.Buffer,\n    // eslint-disable-next-line unicorn/prefer-global-this\n    process: () => process && globalThis.process && global.process,\n    BroadcastChannel: () => !!new BroadcastChannel(\"test\"),\n  },\n  crypto: {\n    createHash: () => {\n      return nodeCrypto.createHash(\"sha256\").update(\"hello\").digest(\"hex\").startsWith(\"2cf24\");\n    },\n  },\n  async_hooks: {\n    AsyncLocalStorage: async () => {\n      const ctx = new nodeAsyncHooks.AsyncLocalStorage();\n      const rand = Math.random();\n      return ctx.run(rand, async () => {\n        await new Promise<void>((r) => r());\n        if (ctx.getStore() !== rand) {\n          return false;\n        }\n        return true;\n      });\n    },\n  },\n  tls: {\n    connect: async () => {\n      // TODO: Use a local TLS server for testing\n      if (\"Bun\" in globalThis || \"Deno\" in globalThis) {\n        return true;\n      }\n      const socket = nodeTLS.connect(443, \"1.1.1.1\");\n      await new Promise<void>((r) => socket.on(\"connect\", r));\n      socket.end();\n      return true;\n    },\n  },\n};\n\nexport default async () => {\n  const results: Record<string, boolean> = {};\n  for (const [group, groupTests] of Object.entries(nodeCompatTests)) {\n    for (const [name, test] of Object.entries(groupTests)) {\n      results[`${group}:${name}`] = await testFn(test);\n    }\n  }\n  return new Response(JSON.stringify(results, null, 2), {\n    headers: {\n      \"Content-Type\": \"application/json\",\n    },\n  });\n};\n\nasync function testFn(fn: () => any) {\n  try {\n    return !!(await fn());\n  } catch {\n    return false;\n  }\n}\n"
  },
  {
    "path": "test/fixture/server/routes/prerender-custom.html.ts",
    "content": "export default () => {\n  const links = [\"/api/hello\", \"/api/param/foo.json\", \"/api/param/foo.css\"];\n\n  return `<!DOCTYPE html><html>\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Prerendered routes test</title>\n</head>\n<body>\n  <h1>Prerendered routes test #2:</h1>\n  <ul>\n${links.map((link) => `    <li><a href=\"${link}\">${link}</a></li>`).join(\"\\n\")}\n  </ul>\n</body>\n</html>`;\n};\n"
  },
  {
    "path": "test/fixture/server/routes/prerender.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => {\n  const links = [\n    \"/404\",\n    \"https://about.google/products/\",\n    \"/api/hello?bar=baz\",\n    \"/api/hello?bar=baz&bing=bap\",\n    \"/api/hello?bar=baz&amp;foo=qux\",\n    \"/prerender#foo\",\n    \"../api/hey\",\n    \"/json-string\",\n    event.url.href.includes(\"?\") ? \"/api/param/hidden\" : \"/prerender?withQuery\",\n  ];\n\n  event.res.headers.append(\"x-nitro-prerender\", \"/api/param/prerender1, /api/param/prerender2\");\n  event.res.headers.append(\"x-nitro-prerender\", \"/api/param/prerender3\");\n\n  event.res.headers.set(\"content-type\", \"text/html\");\n  return /* html */ `<!DOCTYPE html><html>\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Prerendered routes test</title>\n</head>\n<body>\n  <h1>Prerendered routes test:</h1>\n  <ul>\n${links.map((link) => `    <li><a href=\"${link}\">${link}</a></li>`).join(\"\\n\")}\n  </ul>\n  <!-- Bad link Examples -->\n  <link rel=\"icon\" href=\"data:image/png;base64,aaa//bbbbbb/ccc\">\n  <a x-href=\"/500?x-href\">x-href attr</a>\n  &lt;a href=&quot;/500&lt;/a&gt;\n  <a href='#a'>#a</a>\n  <a href='%23b'>#b</a>\n</body>\n</html>`;\n});\n"
  },
  {
    "path": "test/fixture/server/routes/raw.ts",
    "content": "// @ts-ignore\nimport sql from \"raw:../files/sql.sql\";\n\n// https://github.com/nitrojs/nitro/issues/2836\n// @ts-ignore\nimport sqlts from \"../files/sqlts.sql\";\n\nexport default async () => {\n  return {\n    sql: sql.trim(),\n    sqlts: sqlts.trim(),\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/replace.ts",
    "content": "export default () => {\n  // #3672\n  const { window: window$1 = globalThis } = {};\n  return { window: typeof window$1 === \"function\" };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/rules/[...slug].ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nexport default defineHandler((event) => event.url.pathname);\n"
  },
  {
    "path": "test/fixture/server/routes/static-flags.ts",
    "content": "export default async () => {\n  return {\n    dev: import.meta.dev,\n    preset: import.meta.preset,\n    prerender: import.meta.prerender,\n    nitro: import.meta.nitro,\n    server: import.meta.server,\n    client: import.meta.client,\n    baseURL: import.meta.baseURL,\n    _asyncContext: import.meta._asyncContext,\n    _tasks: import.meta._tasks,\n  };\n};\n"
  },
  {
    "path": "test/fixture/server/routes/stream.ts",
    "content": "export default () => {\n  const encoder = new TextEncoder();\n  const stream = new ReadableStream({\n    start(controller) {\n      controller.enqueue(encoder.encode(\"nitro\"));\n      controller.enqueue(encoder.encode(\"is\"));\n      controller.enqueue(encoder.encode(\"awesome\"));\n      controller.close();\n    },\n  });\n  return stream;\n};\n"
  },
  {
    "path": "test/fixture/server/routes/tasks/[...name].ts",
    "content": "import { defineHandler, getQuery } from \"nitro/h3\";\nimport { runTask } from \"nitro/task\";\n\nexport default defineHandler(async (event) => {\n  const name = event.context.params!.name;\n  const payload = { ...getQuery(event) };\n  const { result } = await runTask(name, { payload });\n  return {\n    name,\n    payload,\n    result,\n  };\n});\n"
  },
  {
    "path": "test/fixture/server/routes/wait-until.ts",
    "content": "import { defineHandler } from \"nitro/h3\";\n\nconst timeTakingOperation = async () => {\n  // console.log(\"wait-until.ts: timeTakingOperation() start\");\n  await new Promise((resolve) => setTimeout(resolve, 100));\n  // console.log(\"wait-until.ts: timeTakingOperation() done\");\n};\n\nexport default defineHandler((event) => {\n  event.waitUntil(timeTakingOperation());\n\n  return \"done\";\n});\n"
  },
  {
    "path": "test/fixture/server/routes/wasm/dynamic-import.ts",
    "content": "import { defineLazyEventHandler, defineHandler } from \"nitro/h3\";\n\nexport default defineLazyEventHandler(async () => {\n  // @ts-ignore\n  const { sum } = await import(\"unwasm/examples/sum.wasm\").then((r) => r.default());\n  return defineHandler(() => {\n    return `2+3=${sum(2, 3)}`;\n  });\n});\n"
  },
  {
    "path": "test/fixture/server/routes/wasm/static-import.ts",
    "content": "import { defineHandler, defineLazyEventHandler } from \"nitro/h3\";\n\n// @ts-ignore\nimport init, { sum } from \"unwasm/examples/sum.wasm\";\n\nexport default defineLazyEventHandler(async () => {\n  await init();\n  return defineHandler(() => {\n    return `2+3=${sum(2, 3)}`;\n  });\n});\n"
  },
  {
    "path": "test/fixture/server/tasks/db/migrate.ts",
    "content": "import { defineTask } from \"nitro/task\";\n\nexport default defineTask({\n  meta: {\n    description: \"Run database migrations\",\n  },\n  run() {\n    console.log(\"Running DB migration task...\");\n    return { result: \"Success\" };\n  },\n});\n"
  },
  {
    "path": "test/fixture/server/tasks/test.ts",
    "content": "import { defineTask } from \"nitro/task\";\n\nexport default defineTask({\n  meta: {\n    description: \"task to debug\",\n  },\n  async run(taskEvent) {\n    console.log(\"test task\", taskEvent);\n    if (taskEvent.payload.wait) {\n      await new Promise((resolve) => setTimeout(resolve, Number(taskEvent.payload.wait)));\n    }\n    if (taskEvent.payload.error) {\n      throw new Error(\"test error\");\n    }\n    return { result: taskEvent };\n  },\n});\n"
  },
  {
    "path": "test/fixture/server/utils/foo/bar/test.ts",
    "content": "export const testBarUtil = () => 12_345;\n"
  },
  {
    "path": "test/fixture/server/utils/foo/test.ts",
    "content": "export const testFooUtil = () => 1234;\n"
  },
  {
    "path": "test/fixture/server/utils/test.ts",
    "content": "export const testUtil = () => 123;\n"
  },
  {
    "path": "test/fixture/server.config.ts",
    "content": "export default {\n  \"server-config\": true,\n};\n"
  },
  {
    "path": "test/fixture/server.ts",
    "content": "export default {\n  async fetch(req: Request) {\n    const url = new URL(req.url);\n    if (url.pathname === \"/\") {\n      return new Response(\"server entry works!\");\n    }\n    return new Response(\"404 Not Found\", { status: 404 });\n  },\n};\n"
  },
  {
    "path": "test/fixture/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"mono-jsx\"\n  }\n}\n"
  },
  {
    "path": "test/fixture/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro()],\n});\n"
  },
  {
    "path": "test/fixture/wrangler.toml",
    "content": "compatibility_flags = [\"nodejs_compat\"]\n"
  },
  {
    "path": "test/minimal/minimal.test.ts",
    "content": "import { afterAll, describe, expect, it } from \"vitest\";\nimport { createNitro, build, prepare } from \"nitro/builder\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { mkdir, rm, stat } from \"node:fs/promises\";\nimport { glob } from \"tinyglobby\";\n\nconst fixtureDir = fileURLToPath(new URL(\"./\", import.meta.url));\nconst tmpDir = fileURLToPath(new URL(\".tmp\", import.meta.url));\n\n// Rounded up\nconst bundleSizes: Record<string, [kb: number, minKB: number]> = {\n  rollup: [16, 8],\n  rolldown: [16, 8],\n  vite: [16, 8],\n  vite7: [16, 8],\n};\n\ndescribe(\"minimal fixture\", () => {\n  const builders = [\"rolldown\", \"rollup\", \"vite\", \"vite7\"] as const;\n  const results: any[] = [];\n\n  for (const builder of builders) {\n    for (const minify of [false, true]) {\n      describe(`${builder} (${minify ? \"minified\" : \"unminified\"})`, () => {\n        let buildTime: number, outDir: string;\n        it(\"build\", async () => {\n          outDir = join(tmpDir, \"output\", builder + (minify ? \"-min\" : \"\"));\n          await rm(outDir, { recursive: true, force: true });\n          await mkdir(outDir, { recursive: true });\n          const nitro = await createNitro({\n            rootDir: fixtureDir,\n            minify,\n            output: { dir: outDir },\n            // @ts-expect-error for testing\n            __vitePkg__: builder,\n            builder: builder.includes(\"vite\") ? \"vite\" : (builder as \"rollup\" | \"rolldown\"),\n          });\n          await prepare(nitro);\n          const start = Date.now();\n          await build(nitro);\n          buildTime = Date.now() - start;\n        });\n\n        it(\"server entry works\", async () => {\n          const entry = join(outDir, \"server/index.mjs\");\n          const { fetch } = await import(entry).then((m) => m.default);\n          const res = await fetch(new Request(\"http://localhost/\"));\n          expect(res.status).toBe(200);\n          expect(await res.text()).toBe(\"ok\");\n        });\n\n        it(\"bundle size\", async () => {\n          const { sizeKB } = await analyzeDir(outDir);\n          const expectedSize = bundleSizes[builder]![minify ? 1 : 0];\n          expect(Math.round(sizeKB)).within(expectedSize - 1, expectedSize + 1);\n\n          results.push({\n            builder: builder + (minify ? \" (minified)\" : \"\"),\n            size: sizeKB.toFixed(2) + \" kB\",\n            time: `${buildTime}ms`,\n          });\n        });\n      });\n    }\n  }\n\n  if (process.env.TEST_DEBUG) {\n    afterAll(() => {\n      console.table(results);\n    });\n  }\n});\n\nasync function analyzeDir(cwd: string) {\n  const files = await glob(\"**/*\", { cwd, dot: true });\n  let sizeBytes = 0;\n  await Promise.all(\n    files.map(async (file) => {\n      const { size } = await stat(join(cwd, file));\n      sizeBytes += size;\n    })\n  );\n\n  return {\n    sizeBytes,\n    sizeKB: sizeBytes / 1024,\n    fileCount: files.length,\n  };\n}\n"
  },
  {
    "path": "test/minimal/nitro.config.ts",
    "content": "import { defineNitroConfig } from \"nitro/config\";\n\nexport default defineNitroConfig({\n  preset: \"standard\",\n  // sourcemap: false,\n});\n"
  },
  {
    "path": "test/minimal/package.json",
    "content": "{\n  \"name\": \"nitro-test-fixture-minimal\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"test\": \"TEST_DEBUG=1 vitest\"\n  },\n  \"devDependencies\": {\n    \"nitro\": \"latest\",\n    \"vite\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "test/minimal/server.ts",
    "content": "export default {\n  fetch(_req: Request) {\n    return new Response(\"ok\");\n  },\n};\n"
  },
  {
    "path": "test/minimal/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "test/minimal/vite.config.mjs",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [!process.env.TEST && nitro()],\n});\n"
  },
  {
    "path": "test/presets/aws-lambda.test.ts",
    "content": "import type { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from \"aws-lambda\";\nimport { resolve } from \"pathe\";\nimport { describe } from \"vitest\";\nimport { parseURL, parseQuery } from \"ufo\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:aws-lambda-v2\", async () => {\n  const ctx = await setupTest(\"aws-lambda\");\n  testNitro(ctx, async () => {\n    const { handler } = await import(resolve(ctx.outDir, \"server/index.mjs\"));\n    return async ({ url, headers, method, body }) => {\n      const { pathname, search } = parseURL(url);\n      const event = {\n        rawPath: pathname,\n        headers: headers || {},\n        rawQueryString: search.slice(1),\n        queryStringParameters: parseQuery(search) as Record<string, string>,\n        body: body || \"\",\n        isBase64Encoded: false,\n        version: \"2\",\n        routeKey: \"\",\n        requestContext: {\n          accountId: \"\",\n          apiId: \"\",\n          domainName: \"\",\n          domainPrefix: \"\",\n          requestId: \"\",\n          routeKey: \"\",\n          stage: \"\",\n          time: \"\",\n          timeEpoch: 0,\n          http: {\n            path: url.pathname,\n            protocol: \"http\",\n            userAgent: \"\",\n            sourceIp: \"\",\n            method: method || \"GET\",\n          },\n        },\n      } satisfies APIGatewayProxyEventV2;\n      const res = await handler(event);\n      return webResponse(res);\n    };\n  });\n});\n\ndescribe(\"nitro:preset:aws-lambda-v1\", async () => {\n  const ctx = await setupTest(\"aws-lambda\");\n  testNitro({ ...ctx, lambdaV1: true }, async () => {\n    const { handler } = await import(resolve(ctx.outDir, \"server/index.mjs\"));\n    return async ({ url, headers, method, body }) => {\n      const { pathname, search } = parseURL(url);\n      const event = {\n        stageVariables: {},\n        resource: \"\",\n        httpMethod: method || \"GET\",\n        path: pathname,\n        pathParameters: {},\n        queryStringParameters: parseQuery(search) as Record<string, string>,\n        multiValueQueryStringParameters: {},\n        headers: headers || {},\n        multiValueHeaders: {},\n        body: body || \"\",\n        isBase64Encoded: false,\n        requestContext: {} as any,\n      } satisfies APIGatewayProxyEvent;\n      const res = await handler(event);\n      return webResponse(res);\n    };\n  });\n});\n\nfunction webResponse(awsResponse: any) {\n  const headers = new Headers(awsResponse.headers);\n  const setCookie =\n    awsResponse?.cookies /* v2 */ ?? awsResponse?.multiValueHeaders /* v1 */?.[\"set-cookie\"] ?? [];\n  headers.delete(\"set-cookie\");\n  for (const cookie of setCookie) {\n    if (Array.isArray(cookie)) {\n      for (const c of cookie) {\n        headers.append(\"set-cookie\", c);\n      }\n    } else {\n      headers.append(\"set-cookie\", cookie);\n    }\n  }\n\n  const body = awsResponse.isBase64Encoded\n    ? Buffer.from(awsResponse.body, \"base64\")\n    : (awsResponse.body as string);\n\n  return new Response(body, {\n    status: awsResponse.statusCode,\n    headers,\n  });\n}\n"
  },
  {
    "path": "test/presets/azure-swa.test.ts",
    "content": "import { existsSync, promises as fsp } from \"node:fs\";\nimport { execa } from \"execa\";\nimport { getRandomPort, waitForPort } from \"get-port-please\";\nimport { resolve } from \"pathe\";\nimport { describe, expect, it } from \"vitest\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:azure-swa\", { timeout: 10_000 }, async () => {\n  const customConfig = {\n    routes: [\n      {\n        route: \"/admin\",\n        allowedRoles: [\"authenticated\"],\n      },\n      {\n        route: \"/logout\",\n        redirect: \"/.auth/logout\",\n      },\n      {\n        route: \"/index.html\",\n        redirect: \"/overridden-index\",\n      },\n      {\n        route: \"/\",\n        rewrite: \"/api/server/overridden\",\n      },\n    ],\n    responseOverrides: {\n      401: {\n        statusCode: 302,\n        redirect: \"/.auth/login/aad\",\n      },\n    },\n    networking: {\n      allowedIpRanges: [\"10.0.0.0/24\", \"100.0.0.0/32\", \"192.168.100.0/22\"],\n    },\n    platform: {\n      apiRuntime: \"custom-runtime\",\n    },\n  };\n\n  const ctx = await setupTest(\"azure-swa\", {\n    config: {\n      azure: {\n        config: customConfig,\n      },\n    },\n  });\n\n  if (process.env.TEST_AZURE) {\n    testNitro(ctx, async () => {\n      const port = await getRandomPort();\n      const apiPort = await getRandomPort(); // Avoids conflicts with other tests\n      await new Promise((resolve) => setTimeout(resolve, 500)); // Make sure output is written to disk\n      expect(existsSync(ctx.outDir));\n      const p = execa(\n        \"swa\",\n        `start .output/public --api-location .output/server --host 127.0.0.1 --port ${port} --api-port ${apiPort}`.split(\n          \" \"\n        ),\n        {\n          cwd: resolve(ctx.outDir, \"..\"),\n          stdio: \"inherit\",\n          // stderr: \"inherit\",\n          // stdout: \"ignore\",\n        }\n      );\n      ctx.server = {\n        url: `http://127.0.0.1:${port}`,\n        close: () => p.kill(),\n      } as any;\n      await waitForPort(port, { host: \"127.0.0.1\", retries: 20 });\n      return async ({ url, ...opts }) => {\n        const res = await ctx.fetch(url, opts);\n        return res;\n      };\n    });\n  }\n\n  const config = await fsp\n    .readFile(resolve(ctx.rootDir, \"staticwebapp.config.json\"), \"utf8\")\n    .then((r) => JSON.parse(r));\n\n  it(\"generated the correct config\", () => {\n    expect(config).toMatchInlineSnapshot(`\n        {\n          \"navigationFallback\": {\n            \"rewrite\": \"/api/server\",\n          },\n          \"networking\": {\n            \"allowedIpRanges\": [\n              \"10.0.0.0/24\",\n              \"100.0.0.0/32\",\n              \"192.168.100.0/22\",\n            ],\n          },\n          \"platform\": {\n            \"apiRuntime\": \"custom-runtime\",\n          },\n          \"responseOverrides\": {\n            \"401\": {\n              \"redirect\": \"/.auth/login/aad\",\n              \"statusCode\": 302,\n            },\n          },\n          \"routes\": [\n            {\n              \"allowedRoles\": [\n                \"authenticated\",\n              ],\n              \"route\": \"/admin\",\n            },\n            {\n              \"redirect\": \"/.auth/logout\",\n              \"route\": \"/logout\",\n            },\n            {\n              \"rewrite\": \"/prerender-custom.html\",\n              \"route\": \"/prerender-custom\",\n            },\n            {\n              \"rewrite\": \"/api/hey/index.html\",\n              \"route\": \"/api/hey\",\n            },\n            {\n              \"rewrite\": \"/_swagger/index.html\",\n              \"route\": \"/_swagger\",\n            },\n            {\n              \"rewrite\": \"/_scalar/index.html\",\n              \"route\": \"/_scalar\",\n            },\n            {\n              \"rewrite\": \"/prerender/index.html\",\n              \"route\": \"/prerender\",\n            },\n            {\n              \"redirect\": \"/overridden-index\",\n              \"route\": \"/index.html\",\n            },\n            {\n              \"rewrite\": \"/api/server/overridden\",\n              \"route\": \"/\",\n            },\n          ],\n        }\n      `);\n  });\n});\n"
  },
  {
    "path": "test/presets/bun.test.ts",
    "content": "import { execa, execaCommandSync } from \"execa\";\nimport { getRandomPort, waitForPort } from \"get-port-please\";\nimport { resolve } from \"pathe\";\nimport { describe } from \"vitest\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\nconst hasBun = execaCommandSync(\"bun --version\", { stdio: \"ignore\", reject: false }).exitCode === 0;\n\ndescribe.runIf(hasBun)(\"nitro:preset:bun\", async () => {\n  const ctx = await setupTest(\"bun\");\n  testNitro(ctx, async () => {\n    const port = await getRandomPort();\n    process.env.PORT = String(port);\n    execa(\"bun\", [resolve(ctx.outDir, \"server/index.mjs\")], {\n      stdio: \"inherit\",\n    });\n    ctx.server = {\n      url: `http://127.0.0.1:${port}`,\n      close: () => {\n        // p.kill()\n      },\n    } as any;\n    await waitForPort(port);\n    return async ({ url, ...opts }) => {\n      const res = await ctx.fetch(url, opts);\n      return res;\n    };\n  });\n});\n"
  },
  {
    "path": "test/presets/cloudflare-module.test.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { Miniflare } from \"miniflare\";\nimport { resolve } from \"pathe\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { setupTest, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:cloudflare-module\", async () => {\n  const ctx = await setupTest(\"cloudflare-module\");\n\n  testNitro(ctx, () => {\n    const mf = new Miniflare({\n      modules: true,\n      compatibilityDate: \"2025-04-01\",\n      scriptPath: resolve(ctx.outDir, \"server/index.mjs\"),\n      modulesRules: [{ type: \"CompiledWasm\", include: [\"**/*.wasm\"] }],\n      assets: {\n        directory: resolve(ctx.outDir, \"public\"),\n        routerConfig: { has_user_worker: true },\n        assetConfig: {\n          // https://developers.cloudflare.com/workers/static-assets/routing/#routing-configuration\n          html_handling: \"auto-trailing-slash\" /* default */,\n          not_found_handling: \"none\" /* default */,\n        },\n      },\n      compatibilityFlags: [\"nodejs_compat\", \"no_nodejs_compat_v2\"],\n      bindings: { ...ctx.env },\n    });\n\n    return async ({ url, headers, method, body }) => {\n      const res = await mf.dispatchFetch(\"http://localhost\" + url, {\n        headers: headers || {},\n        method: method || \"GET\",\n        redirect: \"manual\",\n        body,\n      });\n\n      return res as unknown as Response;\n    };\n  });\n\n  it(\"should export the correct functions\", async () => {\n    const entry = await fsp.readFile(resolve(ctx.outDir, \"server\", \"index.mjs\"), \"utf8\");\n    expect(entry).toMatch(/export \\{.*myScheduled.*\\}/);\n  });\n\n  it(\"should auto-generate cron triggers in wrangler.json\", async () => {\n    const wranglerConfig = await fsp\n      .readFile(resolve(ctx.outDir, \"server\", \"wrangler.json\"), \"utf8\")\n      .then((r) => JSON.parse(r));\n    expect(wranglerConfig.triggers).toEqual({\n      crons: [\"* * * * *\"],\n    });\n  });\n});\n"
  },
  {
    "path": "test/presets/cloudflare-pages.test.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { Miniflare } from \"miniflare\";\nimport { resolve } from \"pathe\";\nimport { describe, expect, it } from \"vitest\";\n\nimport { isWindows } from \"std-env\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\ndescribe.skipIf(isWindows)(\"nitro:preset:cloudflare-pages\", async () => {\n  const ctx = await setupTest(\"cloudflare-pages\");\n\n  testNitro(ctx, () => {\n    const mf = new Miniflare({\n      modules: true,\n      compatibilityDate: \"2025-04-01\",\n      scriptPath: resolve(ctx.outDir, \"_worker.js\", \"index.js\"),\n      modulesRules: [{ type: \"CompiledWasm\", include: [\"**/*.wasm\"] }],\n      compatibilityFlags: [\"nodejs_compat\", \"no_nodejs_compat_v2\"],\n      sitePath: \"\",\n      bindings: { ...ctx.env },\n    });\n\n    return async ({ url, headers, method, body }) => {\n      const res = await mf.dispatchFetch(\"http://localhost\" + url, {\n        headers: headers || {},\n        method: method || \"GET\",\n        redirect: \"manual\",\n        body,\n      });\n      return res as unknown as Response;\n    };\n  });\n\n  it(\"should generate a _routes.json\", async () => {\n    const config = await fsp\n      .readFile(resolve(ctx.outDir, \"_routes.json\"), \"utf8\")\n      .then((r) => JSON.parse(r));\n    expect(config).toMatchInlineSnapshot(`\n      {\n        \"exclude\": [\n          \"/blog/static/*\",\n          \"/cf-pages-exclude/*\",\n          \"/build/*\",\n          \"/_openapi.json\",\n          \"/_openapi.json.br\",\n          \"/_openapi.json.gz\",\n          \"/_openapi.json.zst\",\n          \"/_scalar\",\n          \"/_swagger\",\n          \"/favicon.ico\",\n          \"/foo.css\",\n          \"/foo.js\",\n          \"/json-string\",\n          \"/prerender\",\n          \"/prerender-custom\",\n          \"/_scalar/index.html.br\",\n          \"/_scalar/index.html.gz\",\n          \"/_scalar/index.html.zst\",\n          \"/_swagger/index.html.br\",\n          \"/_swagger/index.html.gz\",\n          \"/_swagger/index.html.zst\",\n          \"/api/hello\",\n          \"/api/hey\",\n          \"/prerender/index.html.br\",\n          \"/prerender/index.html.gz\",\n          \"/prerender/index.html.zst\",\n          \"/api/param/foo.json\",\n          \"/api/param/hidden\",\n          \"/api/param/prerender1\",\n          \"/api/param/prerender3\",\n          \"/api/param/prerender4\",\n        ],\n        \"include\": [\n          \"/*\",\n        ],\n        \"version\": 1,\n      }\n    `);\n  });\n\n  it(\"should export the correct functions\", async () => {\n    const entry = await fsp.readFile(resolve(ctx.outDir, \"_worker.js\", \"index.js\"), \"utf8\");\n    expect(entry).toMatch(/export \\{.*myScheduled.*\\}/);\n  });\n});\n"
  },
  {
    "path": "test/presets/deno-server.test.ts",
    "content": "import { execa, execaCommandSync } from \"execa\";\nimport { getRandomPort, waitForPort } from \"get-port-please\";\nimport { describe } from \"vitest\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\nconst hasDeno =\n  execaCommandSync(\"deno --version\", { stdio: \"ignore\", reject: false }).exitCode === 0;\n\ndescribe.runIf(hasDeno)(\"nitro:preset:deno-server\", async () => {\n  const ctx = await setupTest(\"deno-server\");\n  testNitro(ctx, async () => {\n    const port = await getRandomPort();\n    execa(\"deno\", [\"task\", \"start\"], {\n      cwd: ctx.outDir,\n      // stdio: \"inherit\",\n      stdio: \"ignore\",\n      env: {\n        NITRO_PORT: String(port),\n        NITRO_HOST: \"127.0.0.1\",\n      },\n    });\n    ctx.server = {\n      url: `http://127.0.0.1:${port}`,\n      close: () => {\n        // p.kill()\n      },\n    } as any;\n    await waitForPort(port, { delay: 1000, retries: 20, host: \"127.0.0.1\" });\n    return async ({ url, ...opts }) => {\n      const res = await ctx.fetch(url, opts);\n      return res;\n    };\n  });\n});\n"
  },
  {
    "path": "test/presets/netlify.test.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport type { Context as FunctionContext } from \"@netlify/functions\";\nimport { resolve } from \"pathe\";\nimport { describe, expect, it } from \"vitest\";\nimport { getStaticPaths } from \"../../src/presets/netlify/utils.ts\";\nimport { getPresetTmpDir, setupTest, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:netlify\", async () => {\n  const ctx = await setupTest(\"netlify\", {\n    config: {\n      output: {\n        publicDir: resolve(getPresetTmpDir(\"netlify\"), \"dist\"),\n      },\n      netlify: {\n        images: {\n          remote_images: [\"https://example.com/.*\"],\n        },\n      },\n    },\n  });\n  testNitro(\n    ctx,\n    async () => {\n      const { default: handler } = (await import(resolve(ctx.outDir, \"server/main.mjs\"))) as {\n        default: (req: Request, _ctx: FunctionContext) => Promise<Response>;\n      };\n      return async ({ url: rawRelativeUrl, headers, method, body }) => {\n        // creating new URL object to parse query easier\n        const url = new URL(`https://example.com${rawRelativeUrl}`);\n        const req = new Request(url, {\n          headers: headers ?? {},\n          method,\n          body,\n        });\n        const res = await handler(req, {} as FunctionContext);\n        return res;\n      };\n    },\n    (_ctx, callHandler) => {\n      it(\"adds route rules - redirects\", async () => {\n        const redirects = await fsp.readFile(resolve(ctx.outDir, \"../dist/_redirects\"), \"utf8\");\n\n        expect(redirects).toMatchInlineSnapshot(`\n        \"/rules/nested/override\t/other\t302\n        /rules/redirect/wildcard/*\thttps://nitro.build/:splat\t302\n        /rules/redirect/obj\thttps://nitro.build/\t301\n        /rules/nested/*\t/base\t302\n        /rules/redirect\t/base\t302\n        \"\n        `);\n      });\n\n      it(\"adds route rules - headers\", async () => {\n        const headers = await fsp.readFile(resolve(ctx.outDir, \"../dist/_headers\"), \"utf8\");\n\n        expect(headers).toMatchInlineSnapshot(`\n          \"/rules/headers\n            cache-control: s-maxage=60\n          /rules/cors\n            access-control-allow-origin: *\n            access-control-allow-methods: GET\n            access-control-allow-headers: *\n            access-control-max-age: 0\n          /rules/nested/*\n            x-test: test\n          /build/*\n            cache-control: public, max-age=3600, immutable\n          /*\n            x-test: test\n          \"\n        `);\n      });\n\n      it(\"writes config.json\", async () => {\n        const config = await fsp\n          .readFile(resolve(ctx.outDir, \"../deploy/v1/config.json\"), \"utf8\")\n          .then((r) => JSON.parse(r));\n        expect(config).toMatchInlineSnapshot(`\n          {\n            \"images\": {\n              \"remote_images\": [\n                \"https://example.com/.*\",\n              ],\n            },\n          }\n        `);\n      });\n\n      it(\"writes server/server.mjs with static paths excluded\", async () => {\n        const serverFunctionFile = await fsp.readFile(\n          resolve(ctx.outDir, \"server/server.mjs\"),\n          \"utf8\"\n        );\n        expect(serverFunctionFile).toMatchInlineSnapshot(`\n          \"export { default } from \"./main.mjs\";\n          export const config = {\n            name: \"server handler\",\n            generator: \"nitro@3.x\",\n            path: \"/*\",\n            nodeBundler: \"none\",\n            includedFiles: [\"**\"],\n            excludedPath: [\"/.netlify/*\",\"/build/*\"],\n            preferStatic: true,\n          };\"\n        `);\n      });\n\n      describe(\"matching ISR route rule with no max-age\", () => {\n        it(\"sets Netlify-CDN-Cache-Control header with revalidation after 1 year and durable directive\", async () => {\n          const { headers } = await callHandler({ url: \"/rules/isr\" });\n          expect((headers as Record<string, string>)[\"netlify-cdn-cache-control\"]).toBe(\n            \"public, max-age=31536000, must-revalidate, durable\"\n          );\n        });\n\n        it(\"sets Cache-Control header with immediate revalidation\", async () => {\n          const { headers } = await callHandler({ url: \"/rules/isr\" });\n          expect((headers as Record<string, string>)[\"cache-control\"]).toBe(\n            \"public, max-age=0, must-revalidate\"\n          );\n        });\n      });\n\n      describe(\"matching ISR route rule with a max-age\", () => {\n        it(\"sets Netlify-CDN-Cache-Control header with SWC=1yr, given max-age, and durable directive\", async () => {\n          const { headers } = await callHandler({ url: \"/rules/isr-ttl\" });\n          expect((headers as Record<string, string>)[\"netlify-cdn-cache-control\"]).toBe(\n            \"public, max-age=60, stale-while-revalidate=31536000, durable\"\n          );\n        });\n\n        it(\"sets Cache-Control header with immediate revalidation\", async () => {\n          const { headers } = await callHandler({ url: \"/rules/isr-ttl\" });\n          expect((headers as Record<string, string>)[\"cache-control\"]).toBe(\n            \"public, max-age=0, must-revalidate\"\n          );\n        });\n      });\n\n      it(\"does not overwrite Cache-Control headers given a matching non-ISR route rule\", async () => {\n        const { headers } = await callHandler({ url: \"/rules/dynamic\" });\n        expect((headers as Record<string, string>)[\"cache-control\"]).not.toBeDefined();\n        expect((headers as Record<string, string>)[\"netlify-cdn-cache-control\"]).not.toBeDefined();\n      });\n\n      // Regression test for https://github.com/nitrojs/nitro/issues/2431\n      it(\"matches paths with a query string\", async () => {\n        const { headers } = await callHandler({\n          url: \"/rules/isr-ttl?foo=bar\",\n        });\n        expect((headers as Record<string, string>)[\"netlify-cdn-cache-control\"]).toBe(\n          \"public, max-age=60, stale-while-revalidate=31536000, durable\"\n        );\n      });\n    }\n  );\n\n  describe(\"getStaticPaths\", () => {\n    it(\"always returns `/.netlify/*`\", () => {\n      expect(getStaticPaths([], \"/base\")).toEqual([\"/.netlify/*\"]);\n    });\n\n    it(\"returns a pattern with a leading slash for each non-fallthrough non-root public asset path\", () => {\n      const publicAssets = [\n        {\n          fallthrough: true,\n          baseURL: \"with-fallthrough\",\n          dir: \"with-fallthrough-dir\",\n          maxAge: 0,\n        },\n        {\n          fallthrough: true,\n          dir: \"with-fallthrough-no-baseURL-dir\",\n          maxAge: 0,\n        },\n        {\n          fallthrough: false,\n          dir: \"no-fallthrough-no-baseURL-dir\",\n          maxAge: 0,\n        },\n        {\n          fallthrough: false,\n          dir: \"no-fallthrough-root-baseURL-dir\",\n          baseURL: \"/\",\n          maxAge: 0,\n        },\n        {\n          baseURL: \"with-default-fallthrough\",\n          dir: \"with-default-fallthrough-dir\",\n          maxAge: 0,\n        },\n        {\n          fallthrough: false,\n          baseURL: \"nested/no-fallthrough\",\n          dir: \"nested/no-fallthrough-dir\",\n          maxAge: 0,\n        },\n      ];\n      expect(getStaticPaths(publicAssets, \"/base\")).toEqual([\n        \"/.netlify/*\",\n        \"/base/with-default-fallthrough/*\",\n        \"/base/nested/no-fallthrough/*\",\n      ]);\n    });\n  });\n});\n"
  },
  {
    "path": "test/presets/nitro-dev.test.ts",
    "content": "import type { OpenAPI3 } from \"../../src/types/openapi-ts.ts\";\nimport { describe, expect, it } from \"vitest\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:nitro-dev\", async () => {\n  const ctx = await setupTest(\"nitro-dev\");\n  testNitro(\n    ctx,\n    () => {\n      return async ({ url, headers, method, body }) => {\n        const res = await ctx.fetch(url, {\n          headers,\n          method,\n          body,\n        });\n        return res;\n      };\n    },\n    (_ctx, callHandler) => {\n      it.skipIf(process.env.OFFLINE)(\"returns correct status for devProxy\", async () => {\n        const { status } = await callHandler({ url: \"/proxy/example\" });\n        expect(status).toBe(200);\n      });\n\n      describe(\"openAPI\", () => {\n        let spec: OpenAPI3;\n        it(\"/_openapi.json\", async () => {\n          spec = ((await callHandler({ url: \"/_openapi.json\" })) as any).data;\n          expect(spec.openapi).to.match(/^3\\.\\d+\\.\\d+$/);\n          expect(spec.info.title).toBe(\"Nitro Test Fixture\");\n          expect(spec.info.description).toBe(\"Nitro Test Fixture API\");\n        });\n\n        it(\"defineRouteMeta works\", () => {\n          expect(spec.paths?.[\"/api/meta/test\"]).toMatchInlineSnapshot(`\n            {\n              \"get\": {\n                \"description\": \"Test route description\",\n                \"parameters\": [\n                  {\n                    \"in\": \"query\",\n                    \"name\": \"test\",\n                    \"required\": true,\n                  },\n                  {\n                    \"in\": \"query\",\n                    \"name\": \"val\",\n                    \"schema\": {\n                      \"enum\": [\n                        0,\n                        1,\n                      ],\n                      \"type\": \"integer\",\n                    },\n                  },\n                ],\n                \"responses\": {\n                  \"200\": {\n                    \"content\": {\n                      \"application/json\": {\n                        \"schema\": {\n                          \"$ref\": \"#/components/schemas/Test\",\n                        },\n                      },\n                    },\n                    \"description\": \"result\",\n                  },\n                },\n                \"tags\": [\n                  \"test\",\n                ],\n              },\n            }\n          `);\n        });\n      });\n    }\n  );\n});\n"
  },
  {
    "path": "test/presets/node.test.ts",
    "content": "import { existsSync } from \"node:fs\";\nimport { resolve } from \"pathe\";\n// import { isWindows } from \"std-env\";\nimport { describe, expect, it } from \"vitest\";\nimport { setupTest, startServer, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:node-middleware\", async () => {\n  const ctx = await setupTest(\"node-middleware\");\n\n  testNitro(ctx, async () => {\n    const entryPath = resolve(ctx.outDir, \"server/index.mjs\");\n    const { middleware } = await import(entryPath);\n\n    await startServer(ctx, middleware);\n\n    return async ({ url, ...opts }) => {\n      const res = await ctx.fetch(url, opts);\n      return res;\n    };\n  });\n\n  it(\"should handle nested cached route rules\", async () => {\n    const cached = await ctx.fetch(\"/rules/_/noncached/cached\");\n    expect(cached.headers.get(\"etag\")).toBeDefined();\n\n    const noncached = await ctx.fetch(\"/rules/_/noncached/noncached\");\n    expect(noncached.headers.get(\"etag\")).toBeNull();\n\n    const cached2 = await ctx.fetch(\"/rules/_/cached/cached\");\n    expect(cached2.headers.get(\"etag\")).toBeDefined();\n\n    const noncached2 = await ctx.fetch(\"/rules/_/cached/noncached\");\n    expect(noncached2.headers.get(\"etag\")).toBeNull();\n  });\n\n  it(\"should trace externals\", () => {\n    const serverNodeModules = resolve(ctx.outDir, \"server/node_modules\");\n    expect(existsSync(resolve(serverNodeModules, \"@fixture/nitro-utils/extra.mjs\"))).toBe(true);\n  });\n});\n"
  },
  {
    "path": "test/presets/standard.test.ts",
    "content": "import { resolve } from \"pathe\";\nimport { describe } from \"vitest\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\ndescribe(\"nitro:standard\", async () => {\n  const ctx = await setupTest(\"standard\");\n\n  testNitro(ctx, async () => {\n    const entryPath = resolve(ctx.outDir, \"server/index.mjs\");\n    const fetchHandler = await import(entryPath).then((m) => m.default.fetch);\n\n    return async ({ url, ...init }) => {\n      const res = await fetchHandler(new Request(`https://test.com${url}`, init));\n      return res;\n    };\n  });\n});\n"
  },
  {
    "path": "test/presets/static.test.ts",
    "content": "import fsp from \"node:fs/promises\";\nimport { resolve } from \"pathe\";\nimport { describe, expect, it } from \"vitest\";\nimport { setupTest } from \"../tests.ts\";\n\ndescribe(\"nitro:preset:static\", async () => {\n  const ctx = await setupTest(\"static\");\n  it(\"should not generate a server folder\", async () => {\n    const contents = await fsp.readdir(resolve(ctx.outDir));\n    expect(contents).toMatchInlineSnapshot(`\n      [\n        \"nitro.json\",\n        \"public\",\n      ]\n    `);\n  });\n});\n"
  },
  {
    "path": "test/presets/vercel.test.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { resolve, join, basename } from \"pathe\";\nimport { describe, expect, it, vi, beforeAll, afterAll } from \"vitest\";\nimport { setupTest, testNitro, fixtureDir } from \"../tests.ts\";\nimport { toFetchHandler } from \"srvx/node\";\n\ndescribe(\"nitro:preset:vercel:web\", async () => {\n  const ctx = await setupTest(\"vercel\", {\n    outDirSuffix: \"-web\",\n  });\n  testNitro(\n    ctx,\n    async () => {\n      const { fetch: fetchHandler } = await import(\n        resolve(ctx.outDir, \"functions/__server.func/index.mjs\")\n      ).then((r) => r.default || r);\n      return async ({ url, ...options }) => {\n        const req = new Request(new URL(url, \"https://example.com\"), options);\n        const res = await fetchHandler(req, {\n          waitUntil: vi.fn(),\n        });\n        return res;\n      };\n    },\n    () => {\n      it(\"should add route rules to config\", async () => {\n        const config = await fsp\n          .readFile(resolve(ctx.outDir, \"config.json\"), \"utf8\")\n          .then((r) => JSON.parse(r));\n        expect(config).toMatchInlineSnapshot(`\n          {\n            \"crons\": [\n              {\n                \"path\": \"/_vercel/cron\",\n                \"schedule\": \"* * * * *\",\n              },\n            ],\n            \"framework\": {\n              \"name\": \"nitro\",\n              \"version\": \"3.x\",\n            },\n            \"overrides\": {\n              \"_scalar/index.html\": {\n                \"path\": \"_scalar\",\n              },\n              \"_swagger/index.html\": {\n                \"path\": \"_swagger\",\n              },\n              \"api/hey/index.html\": {\n                \"path\": \"api/hey\",\n              },\n              \"prerender/index.html\": {\n                \"path\": \"prerender\",\n              },\n            },\n            \"routes\": [\n              {\n                \"headers\": {\n                  \"Location\": \"https://nitro.build/\",\n                },\n                \"src\": \"/rules/redirect/obj\",\n                \"status\": 308,\n              },\n              {\n                \"headers\": {\n                  \"Location\": \"https://nitro.build/$1\",\n                },\n                \"src\": \"/rules/redirect/wildcard/(.*)\",\n                \"status\": 307,\n              },\n              {\n                \"headers\": {\n                  \"Location\": \"/other\",\n                },\n                \"src\": \"/rules/nested/override\",\n                \"status\": 307,\n              },\n              {\n                \"headers\": {\n                  \"cache-control\": \"s-maxage=60\",\n                },\n                \"src\": \"/rules/headers\",\n              },\n              {\n                \"headers\": {\n                  \"access-control-allow-headers\": \"*\",\n                  \"access-control-allow-methods\": \"GET\",\n                  \"access-control-allow-origin\": \"*\",\n                  \"access-control-max-age\": \"0\",\n                },\n                \"src\": \"/rules/cors\",\n              },\n              {\n                \"headers\": {\n                  \"Location\": \"/base\",\n                },\n                \"src\": \"/rules/redirect\",\n                \"status\": 307,\n              },\n              {\n                \"headers\": {\n                  \"Location\": \"/base\",\n                  \"x-test\": \"test\",\n                },\n                \"src\": \"/rules/nested/(.*)\",\n                \"status\": 307,\n              },\n              {\n                \"headers\": {\n                  \"cache-control\": \"public, max-age=3600, immutable\",\n                },\n                \"src\": \"/build/(.*)\",\n              },\n              {\n                \"headers\": {\n                  \"x-test\": \"test\",\n                },\n                \"src\": \"/(.*)\",\n              },\n              {\n                \"dest\": \"https://cdn.jsdelivr.net/$1\",\n                \"src\": \"/cdn/(.*)\",\n              },\n              {\n                \"continue\": true,\n                \"headers\": {\n                  \"cache-control\": \"public,max-age=31536000,immutable\",\n                },\n                \"src\": \"/build(.*)\",\n              },\n              {\n                \"handle\": \"filesystem\",\n              },\n              {\n                \"dest\": \"/rules/_/noncached/cached-isr?__isr_route=$__isr_route\",\n                \"src\": \"(?<__isr_route>/rules/_/noncached/cached)\",\n              },\n              {\n                \"dest\": \"/__server\",\n                \"src\": \"(?<__isr_route>/rules/_/cached/noncached)\",\n              },\n              {\n                \"dest\": \"/__server\",\n                \"src\": \"(?<__isr_route>/rules/_/noncached/(?:.*))\",\n              },\n              {\n                \"dest\": \"/rules/_/cached/[...]-isr?__isr_route=$__isr_route\",\n                \"src\": \"(?<__isr_route>/rules/_/cached/(?:.*))\",\n              },\n              {\n                \"dest\": \"/__server\",\n                \"src\": \"(?<__isr_route>/rules/dynamic)\",\n              },\n              {\n                \"dest\": \"/rules/isr/[...]-isr?__isr_route=$__isr_route\",\n                \"src\": \"(?<__isr_route>/rules/isr/(?:.*))\",\n              },\n              {\n                \"dest\": \"/rules/isr-ttl/[...]-isr?__isr_route=$__isr_route\",\n                \"src\": \"(?<__isr_route>/rules/isr-ttl/(?:.*))\",\n              },\n              {\n                \"dest\": \"/rules/swr/[...]-isr?__isr_route=$__isr_route\",\n                \"src\": \"(?<__isr_route>/rules/swr/(?:.*))\",\n              },\n              {\n                \"dest\": \"/rules/swr-ttl/[...]-isr?__isr_route=$__isr_route\",\n                \"src\": \"(?<__isr_route>/rules/swr-ttl/(?:.*))\",\n              },\n              {\n                \"dest\": \"/wasm/static-import\",\n                \"src\": \"/wasm/static-import\",\n              },\n              {\n                \"dest\": \"/wasm/dynamic-import\",\n                \"src\": \"/wasm/dynamic-import\",\n              },\n              {\n                \"dest\": \"/wait-until\",\n                \"src\": \"/wait-until\",\n              },\n              {\n                \"dest\": \"/virtual\",\n                \"src\": \"/virtual\",\n              },\n              {\n                \"dest\": \"/stream\",\n                \"src\": \"/stream\",\n              },\n              {\n                \"dest\": \"/static-flags\",\n                \"src\": \"/static-flags\",\n              },\n              {\n                \"dest\": \"/route-group\",\n                \"src\": \"/route-group\",\n              },\n              {\n                \"dest\": \"/replace\",\n                \"src\": \"/replace\",\n              },\n              {\n                \"dest\": \"/raw\",\n                \"src\": \"/raw\",\n              },\n              {\n                \"dest\": \"/prerender-custom.html\",\n                \"src\": \"/prerender-custom.html\",\n              },\n              {\n                \"dest\": \"/prerender\",\n                \"src\": \"/prerender\",\n              },\n              {\n                \"dest\": \"/node-compat\",\n                \"src\": \"/node-compat\",\n              },\n              {\n                \"dest\": \"/modules\",\n                \"src\": \"/modules\",\n              },\n              {\n                \"dest\": \"/jsx\",\n                \"src\": \"/jsx\",\n              },\n              {\n                \"dest\": \"/json-string\",\n                \"src\": \"/json-string\",\n              },\n              {\n                \"dest\": \"/imports\",\n                \"src\": \"/imports\",\n              },\n              {\n                \"dest\": \"/icon.png\",\n                \"src\": \"/icon.png\",\n              },\n              {\n                \"dest\": \"/file\",\n                \"src\": \"/file\",\n              },\n              {\n                \"dest\": \"/fetch\",\n                \"src\": \"/fetch\",\n              },\n              {\n                \"dest\": \"/errors/throw\",\n                \"src\": \"/errors/throw\",\n              },\n              {\n                \"dest\": \"/errors/stack\",\n                \"src\": \"/errors/stack\",\n              },\n              {\n                \"dest\": \"/errors/captured\",\n                \"src\": \"/errors/captured\",\n              },\n              {\n                \"dest\": \"/env\",\n                \"src\": \"/env\",\n              },\n              {\n                \"dest\": \"/context\",\n                \"src\": \"/context\",\n              },\n              {\n                \"dest\": \"/config\",\n                \"src\": \"/config\",\n              },\n              {\n                \"dest\": \"/assets/md\",\n                \"src\": \"/assets/md\",\n              },\n              {\n                \"dest\": \"/assets/all\",\n                \"src\": \"/assets/all\",\n              },\n              {\n                \"dest\": \"/api/upload\",\n                \"src\": \"/api/upload\",\n              },\n              {\n                \"dest\": \"/api/storage/item\",\n                \"src\": \"/api/storage/item\",\n              },\n              {\n                \"dest\": \"/api/methods/get\",\n                \"src\": \"/api/methods/get\",\n              },\n              {\n                \"dest\": \"/api/methods/foo.get\",\n                \"src\": \"/api/methods/foo.get\",\n              },\n              {\n                \"dest\": \"/api/meta/test\",\n                \"src\": \"/api/meta/test\",\n              },\n              {\n                \"dest\": \"/api/kebab\",\n                \"src\": \"/api/kebab\",\n              },\n              {\n                \"dest\": \"/api/hey\",\n                \"src\": \"/api/hey\",\n              },\n              {\n                \"dest\": \"/api/hello\",\n                \"src\": \"/api/hello\",\n              },\n              {\n                \"dest\": \"/api/headers\",\n                \"src\": \"/api/headers\",\n              },\n              {\n                \"dest\": \"/api/echo\",\n                \"src\": \"/api/echo\",\n              },\n              {\n                \"dest\": \"/api/db\",\n                \"src\": \"/api/db\",\n              },\n              {\n                \"dest\": \"/api/cached\",\n                \"src\": \"/api/cached\",\n              },\n              {\n                \"dest\": \"/500\",\n                \"src\": \"/500\",\n              },\n              {\n                \"dest\": \"/_vercel/cron\",\n                \"src\": \"/_vercel/cron\",\n              },\n              {\n                \"dest\": \"/_swagger\",\n                \"src\": \"/_swagger\",\n              },\n              {\n                \"dest\": \"/_scalar\",\n                \"src\": \"/_scalar\",\n              },\n              {\n                \"dest\": \"/_openapi.json\",\n                \"src\": \"/_openapi.json\",\n              },\n              {\n                \"dest\": \"/assets/[id]\",\n                \"src\": \"/assets/(?<id>[^/]+)\",\n              },\n              {\n                \"dest\": \"/api/test/[-]/foo\",\n                \"src\": \"/api/test/(?<_0>[^/]*)/foo\",\n              },\n              {\n                \"dest\": \"/api/param/[test-id]\",\n                \"src\": \"/api/param/(?<test>[^/]+)-id\",\n              },\n              {\n                \"dest\": \"/tasks/[...name]\",\n                \"src\": \"/tasks/?(?<name>.+)\",\n              },\n              {\n                \"dest\": \"/rules/[...slug]\",\n                \"src\": \"/rules/?(?<slug>.+)\",\n              },\n              {\n                \"dest\": \"/api/wildcard/[...param]\",\n                \"src\": \"/api/wildcard/?(?<param>.+)\",\n              },\n              {\n                \"dest\": \"/__server\",\n                \"src\": \"/(.*)\",\n              },\n            ],\n            \"version\": 3,\n          }\n        `);\n      });\n\n      it(\"should generate prerender config\", async () => {\n        const isrRouteConfig = await fsp.readFile(\n          resolve(ctx.outDir, \"functions/rules/isr/[...]-isr.prerender-config.json\"),\n          \"utf8\"\n        );\n        expect(JSON.parse(isrRouteConfig)).toMatchObject({\n          expiration: false,\n          allowQuery: [\"q\", \"__isr_route\"],\n        });\n      });\n\n      const walkDir = async (path: string): Promise<string[]> => {\n        const items: string[] = [];\n        const dirname = basename(path);\n        const entries = await fsp.readdir(path, { withFileTypes: true });\n        for (const entry of entries) {\n          if (entry.isFile()) {\n            items.push(`${dirname}/${entry.name}`);\n          } else if (entry.isSymbolicLink()) {\n            items.push(`${dirname}/${entry.name} (symlink)`);\n          } else if (/_\\/|_.+|node_modules/.test(entry.name)) {\n            items.push(`${dirname}/${entry.name}`);\n          } else if (entry.isDirectory()) {\n            items.push(...(await walkDir(join(path, entry.name))).map((i) => `${dirname}/${i}`));\n          }\n        }\n        items.sort();\n        return items;\n      };\n\n      it(\"should generated expected functions\", async () => {\n        const functionsDir = resolve(ctx.outDir, \"functions\");\n        const functionsFiles = await walkDir(functionsDir);\n        expect(functionsFiles).toMatchInlineSnapshot(`\n          [\n            \"functions/500.func (symlink)\",\n            \"functions/__server.func\",\n            \"functions/_openapi.json.func (symlink)\",\n            \"functions/_scalar.func (symlink)\",\n            \"functions/_swagger.func (symlink)\",\n            \"functions/_vercel\",\n            \"functions/api/cached.func (symlink)\",\n            \"functions/api/db.func (symlink)\",\n            \"functions/api/echo.func (symlink)\",\n            \"functions/api/headers.func (symlink)\",\n            \"functions/api/hello.func (symlink)\",\n            \"functions/api/hey.func (symlink)\",\n            \"functions/api/kebab.func (symlink)\",\n            \"functions/api/meta/test.func (symlink)\",\n            \"functions/api/methods/foo.get.func (symlink)\",\n            \"functions/api/methods/get.func (symlink)\",\n            \"functions/api/param/[test-id].func (symlink)\",\n            \"functions/api/storage/item.func (symlink)\",\n            \"functions/api/test/[-]/foo.func (symlink)\",\n            \"functions/api/upload.func (symlink)\",\n            \"functions/api/wildcard/[...param].func (symlink)\",\n            \"functions/assets/[id].func (symlink)\",\n            \"functions/assets/all.func (symlink)\",\n            \"functions/assets/md.func (symlink)\",\n            \"functions/config.func (symlink)\",\n            \"functions/context.func (symlink)\",\n            \"functions/env.func (symlink)\",\n            \"functions/errors/captured.func (symlink)\",\n            \"functions/errors/stack.func (symlink)\",\n            \"functions/errors/throw.func (symlink)\",\n            \"functions/fetch.func (symlink)\",\n            \"functions/file.func (symlink)\",\n            \"functions/icon.png.func (symlink)\",\n            \"functions/imports.func (symlink)\",\n            \"functions/json-string.func (symlink)\",\n            \"functions/jsx.func (symlink)\",\n            \"functions/modules.func (symlink)\",\n            \"functions/node-compat.func (symlink)\",\n            \"functions/prerender-custom.html.func (symlink)\",\n            \"functions/prerender.func (symlink)\",\n            \"functions/raw.func (symlink)\",\n            \"functions/replace.func (symlink)\",\n            \"functions/route-group.func (symlink)\",\n            \"functions/rules/[...slug].func (symlink)\",\n            \"functions/rules/_/cached/[...]-isr.func (symlink)\",\n            \"functions/rules/_/cached/[...]-isr.prerender-config.json\",\n            \"functions/rules/_/noncached/cached-isr.func (symlink)\",\n            \"functions/rules/_/noncached/cached-isr.prerender-config.json\",\n            \"functions/rules/isr-ttl/[...]-isr.func (symlink)\",\n            \"functions/rules/isr-ttl/[...]-isr.prerender-config.json\",\n            \"functions/rules/isr/[...]-isr.func (symlink)\",\n            \"functions/rules/isr/[...]-isr.prerender-config.json\",\n            \"functions/rules/swr-ttl/[...]-isr.func (symlink)\",\n            \"functions/rules/swr-ttl/[...]-isr.prerender-config.json\",\n            \"functions/rules/swr/[...]-isr.func (symlink)\",\n            \"functions/rules/swr/[...]-isr.prerender-config.json\",\n            \"functions/static-flags.func (symlink)\",\n            \"functions/stream.func (symlink)\",\n            \"functions/tasks/[...name].func (symlink)\",\n            \"functions/virtual.func (symlink)\",\n            \"functions/wait-until.func (symlink)\",\n            \"functions/wasm/dynamic-import.func (symlink)\",\n            \"functions/wasm/static-import.func (symlink)\",\n          ]\n        `);\n      });\n    }\n  );\n});\n\ndescribe(\"nitro:preset:vercel:node\", async () => {\n  const ctx = await setupTest(\"vercel\", {\n    outDirSuffix: \"-node\",\n    config: {\n      vercel: { entryFormat: \"node\" },\n    },\n  });\n  testNitro(ctx, async () => {\n    const nodeHandler = await import(resolve(ctx.outDir, \"functions/__server.func/index.mjs\")).then(\n      (r) => r.default || r\n    );\n    const fetchHandler = toFetchHandler(nodeHandler);\n    return async ({ url, ...options }) => {\n      const req = new Request(new URL(url, \"https://example.com\"), options);\n      const res = await fetchHandler(req);\n      return res;\n    };\n  });\n});\n\ndescribe(\"nitro:preset:vercel:bun\", async () => {\n  const ctx = await setupTest(\"vercel\", {\n    outDirSuffix: \"-bun\",\n    config: {\n      preset: \"vercel\",\n      vercel: {\n        functions: {\n          runtime: \"bun1.x\",\n        },\n      },\n    },\n  });\n\n  it(\"should generate function config with bun runtime\", async () => {\n    const config = await fsp\n      .readFile(resolve(ctx.outDir, \"functions/__server.func/.vc-config.json\"), \"utf8\")\n      .then((r) => JSON.parse(r));\n    expect(config).toMatchInlineSnapshot(`\n      {\n        \"handler\": \"index.mjs\",\n        \"launcherType\": \"Nodejs\",\n        \"runtime\": \"bun1.x\",\n        \"shouldAddHelpers\": false,\n        \"supportsResponseStreaming\": true,\n      }\n    `);\n  });\n});\n\ndescribe.skip(\"nitro:preset:vercel:bun-verceljson\", async () => {\n  const vercelJsonPath = join(fixtureDir, \"vercel.json\");\n\n  const ctx = await setupTest(\"vercel\", {\n    outDirSuffix: \"-bun-verceljson\",\n    config: {\n      preset: \"vercel\",\n    },\n  });\n\n  beforeAll(async () => {\n    // Need to make sure vercel.json is created before setupTest is called\n    await fsp.writeFile(vercelJsonPath, JSON.stringify({ bunVersion: \"1.x\" }));\n  });\n\n  afterAll(async () => {\n    await fsp.unlink(vercelJsonPath).catch(() => {});\n  });\n\n  it(\"should detect bun runtime from vercel.json\", async () => {\n    const config = await fsp\n      .readFile(resolve(ctx.outDir, \"functions/__server.func/.vc-config.json\"), \"utf8\")\n      .then((r) => JSON.parse(r));\n    expect(config).toMatchInlineSnapshot(`\n      {\n        \"handler\": \"index.mjs\",\n        \"launcherType\": \"Nodejs\",\n        \"runtime\": \"bun1.x\",\n        \"shouldAddHelpers\": false,\n        \"supportsResponseStreaming\": true,\n      }\n    `);\n  });\n});\n"
  },
  {
    "path": "test/presets/winterjs.test.ts",
    "content": "import { execa } from \"execa\";\nimport { getRandomPort, waitForPort } from \"get-port-please\";\nimport { describe } from \"vitest\";\nimport { setupTest, testNitro } from \"../tests.ts\";\n\nconst hasWasmer = false;\n// execaCommandSync(\"wasmer --version\", { stdio: \"ignore\", reject: false })\n//   .exitCode === 0;\n\ndescribe.runIf(hasWasmer)(\"nitro:preset:winterjs\", async () => {\n  const ctx = await setupTest(\"winterjs\");\n  testNitro(ctx, async () => {\n    const port = await getRandomPort();\n    const p = execa(\n      \"wasmer\",\n      [\n        \"run\",\n        \"wasmer/winterjs\",\n        \"--forward-host-env\",\n        \"--net\",\n        \"--mapdir\",\n        \"app:\" + ctx.outDir,\n        \"app/server/index.mjs\",\n      ],\n      {\n        stdio: \"inherit\",\n        env: {\n          // ...ctx.env,\n          RUST_BACKTRACE: \"full\",\n          LISTEN_IP: \"127.0.0.1\",\n          PORT: String(port),\n        },\n      }\n    );\n    ctx.server = {\n      url: `http://127.0.0.1:${port}`,\n      close: () => p.kill(),\n    } as any;\n    await waitForPort(port, { delay: 1000, retries: 20, host: \"127.0.0.1\" });\n    return async ({ url, ...opts }) => {\n      const res = await ctx.fetch(url, opts);\n      return res;\n    };\n  });\n});\n"
  },
  {
    "path": "test/scripts/gen-fixture-types.ts",
    "content": "import { fileURLToPath } from \"mlly\";\nimport { createNitro, writeTypes } from \"nitro/builder\";\nimport { resolve } from \"pathe\";\nimport { scanHandlers } from \"../../src/scan.ts\";\n\nconst prepare = async () => {\n  const fixtureDir = fileURLToPath(new URL(\"../fixture\", import.meta.url).href);\n\n  const nitro = await createNitro({\n    rootDir: fixtureDir,\n    serveStatic: true,\n    output: { dir: resolve(fixtureDir, \".output\", \"types\") },\n  });\n\n  await scanHandlers(nitro);\n  await writeTypes(nitro);\n};\n\nprepare();\n"
  },
  {
    "path": "test/tests.ts",
    "content": "import { promises as fsp } from \"node:fs\";\nimport { Server, type RequestListener } from \"node:http\";\nimport { tmpdir } from \"node:os\";\nimport { formatDate } from \"compatx\";\nimport type { DateString } from \"compatx\";\nimport { defu } from \"defu\";\nimport destr from \"destr\";\nimport { fileURLToPath } from \"mlly\";\nimport {\n  build,\n  copyPublicAssets,\n  createDevServer,\n  createNitro,\n  prepare,\n  prerender,\n} from \"nitro/builder\";\nimport type { Nitro, NitroConfig } from \"nitro/types\";\nimport { fetch } from \"ofetch\";\nimport type { FetchOptions } from \"ofetch\";\nimport { join, resolve } from \"pathe\";\nimport { isWindows } from \"std-env\";\nimport { afterAll, beforeAll, describe, expect, it, vi } from \"vitest\";\n\nexport interface Context {\n  preset: string;\n  nitro?: Nitro;\n  rootDir: string;\n  outDir: string;\n  fetch: (url: string, opts?: FetchOptions) => Promise<any>;\n  server?: { url: string; close: () => Promise<void> };\n  isDev: boolean;\n  isWorker: boolean;\n  isLambda: boolean;\n  isIsolated: boolean;\n  supportsEnv: boolean;\n  env: Record<string, string>;\n  lambdaV1?: boolean;\n  // [key: string]: unknown;\n}\n\n// https://github.com/nitrojs/nitro/pull/1240\nexport const describeIf = (condition: boolean, title: string, factory: () => any) =>\n  condition\n    ? describe(title, factory)\n    : describe(title, () => {\n        it.skip(\"skipped\", () => {\n          // Ignore\n        });\n      });\n\nexport const fixtureDir = fileURLToPath(new URL(\"fixture\", import.meta.url).href);\n\nexport const getPresetTmpDir = (preset: string) => {\n  if (preset.startsWith(\"cloudflare\")) {\n    return fileURLToPath(new URL(`.tmp/${preset}`, import.meta.url) as any /* remove me */);\n  }\n\n  return resolve(process.env.NITRO_TEST_TMP_DIR || join(tmpdir(), \"nitro-tests\"), preset);\n};\n\nexport async function setupTest(\n  preset: string,\n  opts: {\n    config?: NitroConfig;\n    compatibilityDate?: DateString;\n    outDirSuffix?: string;\n  } = {}\n) {\n  const presetTmpDir = getPresetTmpDir(preset + (opts.outDirSuffix || \"\"));\n\n  await fsp.rm(presetTmpDir, { recursive: true }).catch(() => {\n    // Ignore\n  });\n  await fsp.mkdir(presetTmpDir, { recursive: true });\n\n  const ctx: Context = {\n    preset,\n    isDev: preset === \"nitro-dev\",\n    isWorker: [\n      \"cloudflare-worker\",\n      \"cloudflare-module\",\n      \"cloudflare-module-legacy\",\n      \"cloudflare-pages\",\n      \"netlify-edge\",\n      \"vercel-edge\",\n      \"winterjs\",\n    ].includes(preset),\n    isLambda: [\"aws-lambda\", \"netlify-legacy\"].includes(preset),\n    isIsolated: [\"winterjs\"].includes(preset),\n    supportsEnv: ![\"winterjs\"].includes(preset),\n    rootDir: fixtureDir,\n    outDir: resolve(fixtureDir, presetTmpDir, \".output\"),\n    env: {\n      NITRO_HELLO: \"world\",\n      CUSTOM_HELLO_THERE: \"general\",\n      SECRET: \"secret\",\n      APP_DOMAIN: \"test.com\",\n      NITRO_DYNAMIC: \"from-env\",\n    },\n    fetch: (url, opts) =>\n      fetch(new URL(url, ctx.server!.url), {\n        redirect: \"manual\",\n        ...(opts as any),\n      }),\n  };\n\n  // Set environment variables for process compatible presets\n  for (const [name, value] of Object.entries(ctx.env)) {\n    process.env[name] = value;\n  }\n\n  const config = defu(opts.config, {\n    preset: ctx.preset,\n    dev: ctx.isDev,\n    rootDir: ctx.rootDir,\n    runtimeConfig: {\n      nitro: {\n        envPrefix: \"CUSTOM_\",\n      },\n      hello: \"\",\n      helloThere: \"\",\n    },\n    buildDir: resolve(fixtureDir, presetTmpDir, \".nitro\"),\n    serveStatic: !ctx.isDev && !ctx.isWorker,\n    output: {\n      dir: ctx.outDir,\n    },\n  });\n  const nitro = (ctx.nitro = await createNitro(config, {\n    compatibilityDate: opts.compatibilityDate || formatDate(new Date()),\n  }));\n\n  if (ctx.isDev) {\n    // Setup development server\n    const devServer = createDevServer(ctx.nitro);\n    const server = await devServer.listen({});\n    ctx.server = {\n      url: server.url!,\n      close: () => server.close(),\n    };\n    await prepare(ctx.nitro);\n    const ready = new Promise<void>((resolve) => {\n      ctx.nitro!.hooks.hook(\"dev:reload\", () => resolve());\n    });\n    await build(ctx.nitro);\n    await ready;\n  } else {\n    // Production build\n    await prepare(nitro);\n    await copyPublicAssets(nitro);\n    await prerender(nitro);\n    await build(nitro);\n  }\n\n  afterAll(async () => {\n    if (ctx.server) {\n      await ctx.server.close();\n    }\n    if (ctx.nitro) {\n      await ctx.nitro.close();\n    }\n  });\n\n  return ctx;\n}\n\nexport async function startServer(ctx: Context, handle: RequestListener) {\n  const server = new Server(handle);\n  await new Promise<void>((resolve, reject) => {\n    server.on(\"error\", reject);\n    server.listen(0, () => resolve());\n  });\n  const port = (server.address() as any).port;\n  ctx.server = {\n    url: `http://localhost:${port}`,\n    close: () =>\n      new Promise((resolve, reject) => {\n        server.close((err) => {\n          if (err) return reject(err);\n          resolve();\n        });\n      }),\n  };\n}\n\ntype TestHandlerResult = {\n  data: any;\n  status: number;\n  statusText?: string;\n  headers: Record<string, string | string[]>;\n};\ntype TestHandler = (options: any) => Promise<TestHandlerResult | Response>;\n\nexport function testNitro(\n  ctx: Context,\n  getHandler: () => TestHandler | Promise<TestHandler>,\n  additionalTests?: (\n    ctx: Context,\n    callHandler: (options: any) => Promise<TestHandlerResult>\n  ) => void\n) {\n  let _handler: TestHandler;\n\n  async function callHandler(\n    options: any,\n    callOpts: { binary?: boolean } = {}\n  ): Promise<TestHandlerResult> {\n    const result = await _handler(options);\n    if (\n      !(result instanceof Response) &&\n      ![\"Response\", \"_Response\"].includes(result.constructor.name)\n    ) {\n      throw new TypeError(\"Expected Response\");\n    }\n\n    const headers: Record<string, string | string[]> = {};\n    for (const [key, value] of (result as Response).headers.entries()) {\n      if (headers[key]) {\n        if (!Array.isArray(headers[key])) {\n          headers[key] = [headers[key] as string];\n        }\n        if (Array.isArray(value)) {\n          (headers[key] as string[]).push(...value);\n        } else {\n          (headers[key] as string[]).push(value);\n        }\n      } else {\n        headers[key] = value;\n      }\n    }\n    headers[\"set-cookie\"] = (result as Response).headers.getSetCookie();\n    if (headers[\"set-cookie\"].length === 0) {\n      delete headers[\"set-cookie\"];\n    }\n\n    return {\n      data: callOpts.binary\n        ? Buffer.from(await (result as Response).arrayBuffer())\n        : destr(await (result as Response).text()),\n      status: result.status,\n      statusText: result.statusText,\n      headers,\n    };\n  }\n\n  beforeAll(async () => {\n    _handler = await getHandler();\n  }, 25_000);\n\n  it(\"Server entry works\", async () => {\n    const { data, headers } = await callHandler({ url: \"/\" });\n    expect(data).toBe(\"server entry works!\");\n    expect(headers[\"x-test\"]).toBe(\"test\");\n  });\n\n  it(\"API Works\", async () => {\n    const { data: helloData } = await callHandler({ url: \"/api/hello\" });\n    expect(helloData).to.toMatchObject({ message: \"Hello API\" });\n\n    if (ctx.nitro?.options.serveStatic) {\n      // /api/hey is expected to be prerendered\n      const { data: heyData } = await callHandler({ url: \"/api/hey\" });\n      expect(heyData).to.have.string(\"Hey API\");\n    }\n\n    const { data: kebabData } = await callHandler({ url: \"/api/kebab\" });\n    expect(kebabData).to.have.string(\"hello-world\");\n\n    const { data: paramsData } = await callHandler({\n      url: \"/api/param/test_param\",\n    });\n    expect(paramsData).toBe(\"test_param\");\n\n    const { data: paramsData2 } = await callHandler({\n      url: \"/api/wildcard/foo/bar/baz\",\n    });\n    expect(paramsData2).toBe(\"foo/bar/baz\");\n  });\n\n  it(\"group routes\", async () => {\n    const { status } = await callHandler({ url: \"/route-group\" });\n    expect(status).toBe(200);\n    const { status: apiStatus } = await callHandler({\n      url: \"/route-group\",\n    });\n    expect(apiStatus).toBe(200);\n  });\n\n  it(\"Handle 404 not found\", async () => {\n    const res = await callHandler({ url: \"/api/not-found\" });\n    expect(res.status).toBe(404);\n  });\n\n  it(\"Virtual route\", async () => {\n    const res = await callHandler({ url: \"/virtual\" });\n    expect(res.status).toBe(200);\n    expect(res.data).toBe(\"Hello from virtual entry!\");\n  });\n\n  // TODO\n  it.todo(\"Handle 405 method not allowed\", async () => {\n    const res = await callHandler({ url: \"/api/upload\" });\n    expect(res.status).toBe(405);\n  });\n\n  it(\"handles route rules - redirects\", async () => {\n    const base = await callHandler({ url: \"/rules/redirect\" });\n    expect(base.status).toBe(307);\n    expect(base.headers.location).toBe(\"/base\");\n\n    const obj = await callHandler({ url: \"/rules/redirect/obj\" });\n    expect(obj.status).toBe(308);\n    expect(obj.headers.location).toBe(\"https://nitro.build/\");\n\n    const wildcard = await callHandler({\n      url: \"/rules/redirect/wildcard/nuxt\",\n    });\n    expect(wildcard.status).toBe(307);\n    expect(wildcard.headers.location).toBe(\"https://nitro.build/nuxt\");\n  });\n\n  it(\"binary response\", async () => {\n    const { data } = await callHandler({ url: \"/icon.png\" }, { binary: true });\n    // Check if buffer is a png\n    function isBufferPng(buffer: Buffer) {\n      return buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47;\n    }\n    expect(isBufferPng(data)).toBe(true);\n  });\n\n  it.skipIf(\n    // TODO: srvx reverse-compat bug with streaming?\n    ctx.preset === \"vercel\" && ctx.nitro?.options.vercel?.entryFormat === \"node\"\n  )(\"render JSX\", async () => {\n    const { data } = await callHandler({ url: \"/jsx\" });\n    expect(data).toMatch(/<h1 class=\"test\".*>Hello JSX!<\\/h1>/);\n  });\n\n  it(\"replace\", async () => {\n    const { data } = await callHandler({ url: \"/replace\" });\n    expect(data).toMatchObject({ window: false });\n  });\n\n  it.runIf(ctx.nitro?.options.serveStatic)(\"handles custom Vary header\", async () => {\n    let headers = (\n      await callHandler({\n        url: \"/foo.css\",\n        headers: { \"Accept-Encoding\": \"gzip\" },\n      })\n    ).headers;\n    if (headers[\"vary\"]) {\n      expect(headers[\"vary\"].includes(\"Origin\")).toBeTruthy();\n      expect(headers[\"vary\"].includes(\"Accept-Encoding\")).toBeTruthy();\n    }\n\n    headers = (\n      await callHandler({\n        url: \"/foo.css\",\n        headers: { \"Accept-Encoding\": \"\" },\n      })\n    ).headers;\n    if (headers[\"vary\"]) {\n      expect(headers[\"vary\"]).toBe(\"Origin\");\n    }\n\n    headers = (\n      await callHandler({\n        url: \"/foo.js\",\n        headers: { \"Accept-Encoding\": \"gzip\" },\n      })\n    ).headers;\n    if (headers[\"vary\"]) {\n      expect(headers[\"vary\"].includes(\"Origin\")).toBeTruthy();\n      expect(headers[\"vary\"].includes(\"Accept-Encoding\")).toBeTruthy();\n    }\n  });\n\n  it(\"handles route rules - headers\", async () => {\n    const { headers } = await callHandler({ url: \"/rules/headers\" });\n    expect(headers[\"cache-control\"]).toBe(\"s-maxage=60\");\n  });\n\n  it(\"handles route rules - cors\", async () => {\n    const expectedHeaders = {\n      \"access-control-allow-origin\": \"*\",\n      \"access-control-allow-methods\": \"GET\",\n      \"access-control-allow-headers\": \"*\",\n      \"access-control-max-age\": \"0\",\n    };\n    const { headers } = await callHandler({ url: \"/rules/cors\" });\n    expect(headers).toMatchObject(expectedHeaders);\n  });\n\n  describe(\"handles route rules - basic auth\", () => {\n    it(\"rejects request with bad creds\", async () => {\n      const { status, headers } = await callHandler({\n        url: \"/rules/basic-auth\",\n        headers: {\n          Authorization: \"Basic \" + btoa(\"user:wrongpass\"),\n        },\n      });\n      expect(status).toBe(401);\n      expect(headers[\"www-authenticate\"]).toBe('Basic realm=\"Secure Area\"');\n    });\n\n    it(\"allows request with correct password\", async () => {\n      const { status } = await callHandler({\n        url: \"/rules/basic-auth/test\",\n        headers: {\n          Authorization: \"Basic \" + btoa(\"admin:secret\"),\n        },\n      });\n      expect(status).toBe(200);\n    });\n\n    it(\"disabled basic-auth for sub-rules\", async () => {\n      const { status } = await callHandler({ url: \"/rules/basic-auth/no-auth\" });\n      expect(status).toBe(200);\n    });\n  });\n\n  it(\"handles route rules - allowing overriding\", async () => {\n    const override = await callHandler({ url: \"/rules/nested/override\" });\n    expect(override.headers.location).toBe(\"/other\");\n    expect(override.headers[\"x-test\"]).toBe(\"test\");\n\n    const base = await callHandler({ url: \"/rules/nested/base\" });\n    expect(base.headers.location).toBe(\"/base\");\n    expect(base.headers[\"x-test\"]).toBe(\"test\");\n  });\n\n  it.skipIf(\n    // TODO!\n    ctx.preset === \"vercel\" && ctx.nitro?.options.vercel?.entryFormat === \"node\" && isWindows\n  )(\"handles custom server assets\", async () => {\n    const { data: html, status: htmlStatus } = await callHandler({\n      url: \"/file?filename=index.html\",\n    });\n    expect(htmlStatus).toBe(200);\n    expect(html).toContain(\"<h1>nitro is amazing!</h1>\");\n\n    const { data: txtFile, status: txtStatus } = await callHandler({\n      url: \"/file?filename=test.txt\",\n    });\n    expect(txtStatus).toBe(200);\n    expect(txtFile).toContain(\"this is an asset from a text file from nitro\");\n\n    const { data: mdFile, status: mdStatus } = await callHandler({\n      url: \"/assets/md\",\n    });\n    expect(mdStatus).toBe(200);\n    expect(mdFile).toContain(\"# Hello world\");\n  });\n\n  if (ctx.nitro!.options.serveStatic) {\n    it(\"serve static asset /favicon.ico\", async () => {\n      const { status, headers } = await callHandler({ url: \"/favicon.ico\" });\n      expect(status).toBe(200);\n      expect(headers.etag).toBeDefined();\n      expect(headers[\"content-type\"]).toBe(\"image/vnd.microsoft.icon\");\n    });\n\n    it(\"serve static asset /build/test.txt\", async () => {\n      const { status, headers } = await callHandler({ url: \"/build/test.txt\" });\n      expect(status).toBe(200);\n      expect(headers.etag).toBe('\"7-vxGfAKTuGVGhpDZqQLqV60dnKPw\"');\n      expect(headers[\"content-type\"]).toBe(\"text/plain; charset=utf-8\");\n    });\n\n    it(\"stores content-type for prerendered routes\", async () => {\n      const { data, headers } = await callHandler({\n        url: \"/api/param/prerender4\",\n      });\n      expect(data).toBe(\"prerender4\");\n      expect(headers[\"content-type\"]).toBe(\"text/plain; custom\");\n    });\n  }\n\n  it(\"shows 404 for /build/non-file\", async () => {\n    const { status } = await callHandler({ url: \"/build/non-file\" });\n    expect(status).toBe(404);\n  });\n\n  it(\"find auto imported utils\", async () => {\n    const res = await callHandler({ url: \"/imports\" });\n    expect(res.data).toMatchObject({\n      testUtil: 123,\n      testNestedUtil: 1234 + 12_345,\n    });\n  });\n\n  it.skipIf(ctx.preset === \"deno-server\")(\"resolve module version conflicts\", async () => {\n    const { data } = await callHandler({ url: \"/modules\" });\n    expect(data).toMatchObject({\n      depA: \"@fixture/nitro-lib@1.0.0+@fixture/nested-lib@1.0.0\",\n      depB: \"@fixture/nitro-lib@2.0.1+@fixture/nested-lib@2.0.1\",\n      depLib: \"@fixture/nitro-lib@2.0.0+@fixture/nested-lib@2.0.0\",\n      subpathLib: \"@fixture/nitro-lib@2.0.0\",\n      extraUtils: \"@fixture/nitro-utils/extra\",\n    });\n  });\n\n  it.skipIf(ctx.isIsolated)(\"useStorage (with base)\", { retry: 5 }, async () => {\n    const putRes = await callHandler({\n      url: \"/api/storage/item?key=test:hello\",\n      method: \"PUT\",\n      body: `\"world\"`,\n    });\n    expect(putRes.data).toBe(\"world\");\n\n    expect(\n      (\n        await callHandler({\n          url: \"/api/storage/item?key=:\",\n        })\n      ).data\n    ).toMatchObject([\"test:hello\"]);\n\n    expect(\n      (\n        await callHandler({\n          url: \"/api/storage/item?base=test&key=:\",\n        })\n      ).data\n    ).toMatchObject([\"hello\"]);\n\n    expect(\n      (\n        await callHandler({\n          url: \"/api/storage/item?base=test&key=hello\",\n        })\n      ).data\n    ).toBe(\"world\");\n  });\n\n  if (additionalTests) {\n    additionalTests(ctx, callHandler);\n  }\n\n  it(\"runtime proxy\", async () => {\n    const { data } = await callHandler({\n      url: \"/api/proxy?foo=bar\",\n      headers: {\n        \"x-test\": \"foobar\",\n      },\n    });\n    expect(data.url).toBe(\"/api/echo?foo=bar\");\n    if (!(ctx.preset === \"vercel\" && ctx.nitro?.options.vercel?.entryFormat === \"node\")) {\n      // TODO: Investigate why headers are missing in this case\n      expect(data.headers[\"x-test\"]).toBe(\"foobar\");\n    }\n  });\n\n  it(\"external proxy\", async () => {\n    const { data, headers, status } = await callHandler({\n      url: \"/cdn/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js\",\n    });\n    expect(status).toBe(200);\n    expect(headers[\"etag\"]).toMatch(/W\\/\".+\"/);\n    expect(data).toContain(\"Bootstrap\");\n  });\n\n  it.skipIf(ctx.preset === \"bun\" /* TODO */)(\"stream\", async () => {\n    const { data } = await callHandler({\n      url: \"/stream\",\n    });\n    expect(data).toBe(\"nitroisawesome\");\n  });\n\n  it.skipIf(!ctx.supportsEnv)(\"config\", async () => {\n    const { data } = await callHandler({\n      url: \"/config\",\n    });\n    expect(data).toMatchObject({\n      runtimeConfig: {\n        dynamic: \"from-env\",\n        url: \"https://test.com\",\n        app: {\n          baseURL: \"/\",\n        },\n      },\n      sharedRuntimeConfig: {\n        dynamic: ctx.preset === \"cloudflare-module-legacy\" ? \"initial\" : \"from-env\",\n        // url: \"https://test.com\",\n        app: {\n          baseURL: \"/\",\n        },\n      },\n    });\n  });\n\n  it(\"static build flags\", async () => {\n    const { data } = await callHandler({ url: \"/static-flags\" });\n    expect(data).toMatchObject({\n      dev: ctx.isDev,\n      preset: ctx.preset,\n      prerender: false,\n      nitro: true,\n      server: true,\n      client: false,\n      baseURL: \"/\",\n      _asyncContext: true,\n      _tasks: true,\n    });\n  });\n\n  it(\"event.waitUntil\", async () => {\n    const res = await callHandler({ url: \"/wait-until\" });\n    expect(res.data).toBe(\"done\");\n  });\n\n  describe(\"ignore\", () => {\n    it(\"server routes should be ignored\", async () => {\n      expect((await callHandler({ url: \"/api/_ignored\" })).status).toBe(404);\n      expect((await callHandler({ url: \"/_ignored\" })).status).toBe(404);\n    });\n\n    it.skipIf(ctx.isWorker || ctx.isDev)(\"public files should be ignored\", async () => {\n      expect((await callHandler({ url: \"/_ignored.txt\" })).status).toBe(404);\n      expect((await callHandler({ url: \"/favicon.ico\" })).status).toBe(200);\n    });\n  });\n\n  describe(\"headers\", () => {\n    it(\"handles headers correctly\", async () => {\n      const { headers } = await callHandler({ url: \"/api/headers\" });\n      expect(headers[\"x-foo\"]).toBe(\"bar\");\n      expect(headers[\"x-array\"]).toMatch(/^foo,\\s?bar$/);\n      const expectedCookies: string | string[] = [\n        \"foo=bar\",\n        \"bar=baz\",\n        \"test=value; Path=/\",\n        \"test2=value; Path=/\",\n      ];\n      expect(headers[\"set-cookie\"]).toMatchObject(expectedCookies);\n    });\n  });\n\n  describe(\"errors\", () => {\n    it.skipIf(ctx.isIsolated)(\"captures errors\", async () => {\n      await callHandler({ url: \"/errors/throw\" });\n      const { data } = await callHandler({ url: \"/errors/captured\" });\n      const allErrorMessages = (data.allErrors || []).map((entry: any) => entry.message);\n      expect(allErrorMessages).to.includes(\"Handled error\");\n    });\n\n    it.skipIf(\n      !ctx.nitro!.options.node ||\n        // TODO: Investigate\n        ctx.preset === \"bun\" ||\n        ctx.preset === \"deno-server\" ||\n        ctx.preset === \"nitro-dev\"\n    )(\"sourcemap works\", async () => {\n      const { data } = await callHandler({ url: \"/errors/stack\" });\n      expect(data.stack).toMatch(\"test/fixture/server/routes/errors/stack.ts\");\n    });\n\n    for (const errorAction of [\"throw\", \"return\"]) {\n      it(`handled errors (${errorAction})`, async () => {\n        const res = await callHandler({ url: `/errors/throw?handled&action=${errorAction}` });\n        expect(res).toMatchObject({\n          status: 503,\n          statusText: /deno|bun/.test(ctx.preset)\n            ? \"Service Unavailable\"\n            : /aws/.test(ctx.preset)\n              ? \"\"\n              : \"Custom Status Text\",\n          headers: {\n            \"content-type\": \"application/json; charset=utf-8\",\n            \"x-custom-error\": \"custom-value\",\n          },\n          data: {\n            error: true,\n            status: 503,\n            statusText: \"Custom Status Text\",\n            message: \"Handled error\",\n            data: { custom: \"data\" },\n            custom: \"body\",\n          },\n        });\n      });\n\n      it(`unhandled errors (${errorAction})`, async () => {\n        const stderrMock = vi.spyOn(process.stderr, \"write\").mockImplementation(() => true);\n        const consoleErrorMock = vi.spyOn(console, \"error\").mockImplementation(() => {});\n        let res;\n        try {\n          res = await callHandler({\n            url: `/errors/throw?unhandled&action=${errorAction}`,\n            headers: { Accept: \"application/json\" },\n          });\n        } finally {\n          stderrMock.mockRestore();\n          consoleErrorMock.mockRestore();\n        }\n        // TODO\n        // expect(consoleErrorMock).toHaveBeenCalledExactlyOnceWith(\n        //   expect.stringContaining(\"Unhandled error\")\n        // );\n        if (!ctx.isDev) {\n          // Prod\n          expect(res).toMatchObject({\n            status: 500,\n            headers: {\n              \"content-type\": \"application/json; charset=utf-8\",\n            },\n            data: {\n              error: true,\n              unhandled: true,\n              status: 500,\n            },\n          });\n        } else {\n          // Dev\n          expect(res).toMatchObject({\n            status: 500,\n            headers: {\n              \"content-type\": \"application/json; charset=utf-8\",\n            },\n            data: {\n              error: true,\n              unhandled: true,\n              status: 500,\n              message: \"HTTPError\",\n              stack: expect.arrayContaining([\"Unhandled error\"]),\n            },\n          });\n        }\n      });\n    }\n  });\n\n  describe(\"async context\", () => {\n    it.skipIf(!ctx.nitro!.options.node)(\"works\", async () => {\n      const { data } = await callHandler({ url: \"/context?foo\" });\n      expect(data).toMatchObject({\n        context: {\n          path: \"/context?foo\",\n        },\n      });\n    });\n  });\n\n  describe.skipIf(!ctx.supportsEnv)(\"environment variables\", () => {\n    it(\"can load environment variables from runtimeConfig\", async () => {\n      const { data } = await callHandler({ url: \"/config\" });\n      expect(data.runtimeConfig.hello).toBe(\"world\");\n      expect(data.runtimeConfig.helloThere).toBe(\"general\");\n      expect(data.runtimeConfig.secret).toBeUndefined();\n    });\n  });\n\n  describe(\"cache\", () => {\n    it.skipIf(ctx.isIsolated || (isWindows && ctx.preset === \"nitro-dev\"))(\n      \"should setItem before returning response the first time\",\n      async () => {\n        const {\n          data: { timestamp },\n        } = await callHandler({ url: \"/api/cached\" });\n\n        // TODO\n        // expect(eventContextCache?.options.swr).toBe(true);\n\n        const calls = await Promise.all([\n          callHandler({ url: \"/api/cached\" }),\n          callHandler({ url: \"/api/cached\" }),\n          callHandler({ url: \"/api/cached\" }),\n        ]);\n\n        for (const call of calls) {\n          expect(call.data.timestamp).toBe(timestamp);\n          // TODO\n          // expect(call.data.eventContextCache.options.swr).toBe(true);\n        }\n      }\n    );\n  });\n\n  describe(\"scanned files\", () => {\n    it(\"Allow having extra method in file name\", async () => {\n      expect((await callHandler({ url: \"/api/methods/get\" })).data).toBe(\"get\");\n      expect((await callHandler({ url: \"/api/methods/foo.get\" })).data).toBe(\"foo.get\");\n    });\n  });\n\n  describe.skipIf(ctx.preset === \"cloudflare-worker\")(\"wasm\", () => {\n    it(\"dynamic import wasm\", async () => {\n      expect((await callHandler({ url: \"/wasm/dynamic-import\" })).data).toBe(\"2+3=5\");\n    });\n\n    it(\"static import wasm\", async () => {\n      expect((await callHandler({ url: \"/wasm/static-import\" })).data).toBe(\"2+3=5\");\n    });\n  });\n\n  describe.skipIf(\n    isWindows ||\n      !ctx.nitro!.options.node ||\n      ctx.isLambda ||\n      ctx.isWorker ||\n      [\"bun\", \"deno-server\", \"deno-deploy\", \"netlify\", \"netlify-legacy\"].includes(ctx.preset)\n  )(\"Database\", () => {\n    it(\"works\", async () => {\n      const { data } = await callHandler({ url: \"/api/db\" });\n      expect(data).toMatchObject({\n        rows: [\n          {\n            id: \"1001\",\n            firstName: \"John\",\n            lastName: \"Doe\",\n            email: \"\",\n          },\n        ],\n      });\n    });\n  });\n\n  describe(\"Environment specific routes\", () => {\n    it(\"filters based on dev|prod\", async () => {\n      const { data } = await callHandler({ url: \"/env\" });\n      expect(data).toBe(ctx.isDev ? \"dev env\" : \"prod env\");\n    });\n  });\n\n  it(\"raw imports\", async () => {\n    const { data } = await callHandler({ url: \"/raw\" });\n    expect(data).toMatchObject({\n      sql: \"--\",\n      sqlts: \"--\",\n    });\n  });\n\n  it.skipIf(\n    process.env.OFFLINE /* connect */ ||\n      [\"cloudflare-worker\", \"cloudflare-module-legacy\"].includes(ctx.preset)\n  )(\"nodejs compatibility\", async () => {\n    const { data, status } = await callHandler({ url: \"/node-compat\" });\n    expect(status).toBe(200);\n    for (const key in data) {\n      if (ctx.preset === \"vercel-edge\" && key === \"crypto:createHash\") {\n        continue;\n      }\n      if (ctx.preset === \"deno-server\" && key === \"globals:BroadcastChannel\") {\n        continue; // unstable API\n      }\n      if (\n        ctx.preset.includes(\"cloudflare\") &&\n        key.startsWith(\"globals:\") &&\n        ctx.nitro!.options.builder === \"rolldown\"\n      ) {\n        continue;\n      }\n      expect(data[key], key).toBe(true);\n    }\n  });\n}\n"
  },
  {
    "path": "test/unit/azure.utils.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { getAzureParsedCookiesFromHeaders } from \"../../src/presets/azure/runtime/_utils.ts\";\n\ndescribe(\"getAzureParsedCookiesFromHeaders\", () => {\n  it(\"returns empty array if no cookies\", () => {\n    expect(getAzureParsedCookiesFromHeaders(new Headers({}))).toMatchObject([]);\n  });\n  it(\"returns empty array if empty set-cookie header\", () => {\n    expect(getAzureParsedCookiesFromHeaders(new Headers({ \"set-cookie\": \" \" }))).toMatchObject([]);\n  });\n  it(\"returns single cookie\", () => {\n    expect(\n      getAzureParsedCookiesFromHeaders(new Headers({ \"set-cookie\": \"foo=bar\" }))\n    ).toMatchObject([\n      {\n        name: \"foo\",\n        value: \"bar\",\n      },\n    ]);\n  });\n  it('returns cookie with \"expires\" attribute', () => {\n    expect(\n      getAzureParsedCookiesFromHeaders(\n        new Headers({\n          \"set-cookie\": \"foo=bar; expires=Thu, 01 Jan 1970 00:00:00 GMT\",\n        })\n      )\n    ).toMatchObject([\n      {\n        name: \"foo\",\n        value: \"bar\",\n        expires: new Date(\"1970-01-01T00:00:00.000Z\"),\n      },\n    ]);\n  });\n  it(\"returns a complex cookie\", () => {\n    expect(\n      getAzureParsedCookiesFromHeaders(\n        new Headers({\n          \"set-cookie\":\n            \"session=xyz; Path=/; Expires=Sun, 24 Mar 2024 09:13:27 GMT; HttpOnly; SameSite=Strict\",\n        })\n      )\n    ).toMatchObject([\n      {\n        name: \"session\",\n        value: \"xyz\",\n        expires: new Date(\"2024-03-24T09:13:27.000Z\"),\n        path: \"/\",\n        sameSite: \"Strict\",\n        httpOnly: true,\n      },\n    ]);\n  });\n  it(\"returns multiple cookies\", () => {\n    expect(\n      getAzureParsedCookiesFromHeaders(\n        new Headers([\n          [\"set-cookie\", \"foo=bar\"],\n          [\"set-cookie\", \"baz=qux\"],\n        ])\n      )\n    ).toMatchObject([\n      {\n        name: \"foo\",\n        value: \"bar\",\n      },\n      {\n        name: \"baz\",\n        value: \"qux\",\n      },\n    ]);\n  });\n});\n"
  },
  {
    "path": "test/unit/bump-version.test.ts",
    "content": "import { describe, it, expect, vi, beforeEach } from \"vitest\";\nimport { valid as semverValid } from \"semver\";\n\nvi.mock(\"node:fs\", () => ({\n  promises: {\n    readFile: vi.fn(),\n    writeFile: vi.fn(),\n  },\n}));\n\nconst fetchMock = vi.fn();\nvi.stubGlobal(\"fetch\", fetchMock);\n\nfunction mockRegistry(versions: string[]) {\n  fetchMock.mockResolvedValue({\n    ok: true,\n    json: async () => ({ versions: Object.fromEntries(versions.map((v) => [v, {}])) }),\n  });\n}\n\nbeforeEach(() => {\n  vi.restoreAllMocks();\n  fetchMock.mockReset();\n});\n\ndescribe(\"fmtDate\", async () => {\n  const { fmtDate } = await import(\"../../scripts/bump-version.ts\");\n\n  it(\"formats date as YYMMDD\", () => {\n    expect(fmtDate(new Date(\"2026-03-11\"))).toBe(\"260311\");\n    expect(fmtDate(new Date(\"2025-01-05\"))).toBe(\"250105\");\n  });\n});\n\ndescribe(\"resolveVersion\", async () => {\n  const { resolveVersion } = await import(\"../../scripts/bump-version.ts\");\n\n  const cases = [\n    { name: \"no existing versions\", existing: [], expected: \"3.0.260311-beta\" },\n    { name: \"one existing version\", existing: [\"3.0.260311-beta\"], expected: \"3.0.260311-beta.2\" },\n    {\n      name: \"multiple existing versions\",\n      existing: [\"3.0.260311-beta\", \"3.0.260311-beta.2\"],\n      expected: \"3.0.260311-beta.3\",\n    },\n    {\n      name: \"other dates only\",\n      existing: [\"3.0.260310-beta\", \"3.0.260310-beta.3\"],\n      expected: \"3.0.260311-beta\",\n    },\n    {\n      name: \"without prerelease tag\",\n      existing: [\"3.0.260311-1\", \"3.0.260311-2\"],\n      expected: \"3.0.260311-3\",\n      prerelease: \"\",\n    },\n    {\n      name: \"without prerelease, no existing\",\n      existing: [],\n      expected: \"3.0.260311\",\n      prerelease: \"\",\n    },\n  ];\n\n  for (const { name, existing, expected, prerelease } of cases) {\n    it(`${name}: ${existing.join(\", \") || \"(none)\"} → ${expected}`, async () => {\n      mockRegistry(existing);\n      const version = await resolveVersion(\n        \"nitro\",\n        \"260311\",\n        ...(prerelease !== undefined ? [prerelease] : [])\n      );\n      expect(version).toBe(expected);\n      expect(semverValid(version)).toBe(version);\n    });\n  }\n});\n"
  },
  {
    "path": "test/unit/chunks.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport type { Nitro } from \"nitro/types\";\nimport {\n  NODE_MODULES_RE,\n  libChunkName,\n  pathToPkgName,\n  getChunkName,\n  routeToFsPath,\n} from \"../../src/build/chunks.ts\";\n\nfunction createChunk(name: string, moduleIds: string[]): { name: string; moduleIds: string[] } {\n  return { name, moduleIds };\n}\n\nfunction createNitro(overrides: Partial<Nitro> = {}): Nitro {\n  return {\n    options: { buildDir: \"/build\", tasks: {}, ...overrides.options },\n    routing: {\n      routes: { routes: [] },\n      ...overrides.routing,\n    },\n    ...overrides,\n  } as unknown as Nitro;\n}\n\ndescribe(\"NODE_MODULES_RE\", () => {\n  it.each([\n    [\"/foo/node_modules/bar/index.js\", true],\n    [\"node_modules/bar/index.js\", true],\n    [\"node_modules\\\\bar\\\\index.js\", true],\n    [\"/foo/node_modules/nitro/dist/index.js\", false],\n    [\"/foo/node_modules/nitro-nightly/dist/index.js\", false],\n    [\"/foo/node_modules/.nitro\", false],\n    [\"/foo/node_modules/.cache\", false],\n    [\"/foo/src/bar.js\", false],\n  ])(\"%s → %s\", (path, expected) => {\n    expect(NODE_MODULES_RE.test(path)).toBe(expected);\n  });\n});\n\ndescribe(\"pathToPkgName\", () => {\n  it.each([\n    [\"/foo/node_modules/express/index.js\", \"express\"],\n    [\"/foo/node_modules/@h3/core/index.js\", \"@h3/core\"],\n    [\"C:\\\\proj\\\\node_modules\\\\express\\\\index.js\", \"express\"],\n    [\"C:\\\\proj\\\\node_modules\\\\@h3\\\\core\\\\index.js\", \"@h3\\\\core\"],\n    [\"/node_modules/nitro-nightly/dist/index.js\", \"nitro\"],\n    [\"/node_modules/a/node_modules/b/index.js\", \"b\"],\n    [\"/foo/src/bar.js\", undefined],\n  ])(\"%s → %s\", (path, expected) => {\n    expect(pathToPkgName(path)).toBe(expected);\n  });\n});\n\ndescribe(\"libChunkName\", () => {\n  it.each([\n    [\"/node_modules/express/index.js\", \"_libs/express\"],\n    [\"/node_modules/@h3/core/index.js\", \"_libs/@h3/core\"],\n    [\"/src/utils/foo.ts\", undefined],\n    [\"/node_modules/nitro-nightly/dist/index.js\", \"_libs/nitro\"],\n  ])(\"%s → %s\", (id, expected) => {\n    expect(libChunkName(id)).toBe(expected);\n  });\n});\n\ndescribe(\"routeToFsPath\", () => {\n  it.each([\n    [\"/api/hello\", \"api/hello\"],\n    [\"/api/users/:id\", \"api/users/[id]\"],\n    [\"/\", \"index\"],\n    [\"/api/users/:id/posts/*\", \"api/users/[id]/posts/[...]\"],\n  ])(\"%s → %s\", (route, expected) => {\n    expect(routeToFsPath(route)).toBe(expected);\n  });\n});\n\ndescribe(\"getChunkName\", () => {\n  const nitro = createNitro();\n\n  it.each<[string, { name: string; moduleIds: string[] }, string]>([\n    [\"rolldown-runtime\", createChunk(\"rolldown-runtime\", []), \"_runtime.mjs\"],\n    [\"_ chunks are preserved\", createChunk(\"_shared\", [\"/src/foo.ts\"]), \"_shared.mjs\"],\n    [\n      \"all node_modules (sorted a-z)\",\n      createChunk(\"vendor\", [\"/node_modules/express/index.js\", \"/node_modules/h3/dist/index.mjs\"]),\n      \"_libs/express+h3.mjs\",\n    ],\n    [\n      \"single node_modules package\",\n      createChunk(\"vendor\", [\"/node_modules/a/index.js\"]),\n      \"_libs/a.mjs\",\n    ],\n    [\n      \"node_modules names exceed 30 chars\",\n      createChunk(\"_libs/vendor\", [\n        \"/node_modules/some-very-long-package-name/index.js\",\n        \"/node_modules/another-very-long-name/index.js\",\n      ]),\n      \"_libs/vendor+[...].mjs\",\n    ],\n    [\n      \"3 node_modules sorted a-z\",\n      createChunk(\"vendor\", [\n        \"/node_modules/zod/index.js\",\n        \"/node_modules/ab/index.js\",\n        \"/node_modules/h3/dist/index.mjs\",\n      ]),\n      \"_libs/ab+h3+zod.mjs\",\n    ],\n    [\n      \"scoped packages use __ separator\",\n      createChunk(\"vendor\", [\"/node_modules/@h3/core/index.js\", \"/node_modules/defu/index.js\"]),\n      \"_libs/defu+h3__core.mjs\",\n    ],\n    [\"empty moduleIds (vacuous every())\", createChunk(\"my-chunk\", []), \"_libs/_.mjs\"],\n    [\n      \"virtual:raw modules\",\n      createChunk(\"raw\", [\"\\0virtual:raw:foo\", \"#virtual:raw:bar\"]),\n      \"_raw/[name].mjs\",\n    ],\n    [\"all virtual modules\", createChunk(\"virt\", [\"\\0something\", \"#other\"]), \"_virtual/[name].mjs\"],\n    [\"wasm modules\", createChunk(\"wasm\", [\"/src/module.wasm\"]), \"_wasm/[name].mjs\"],\n    [\n      \"vite/services modules\",\n      createChunk(\"ssr\", [\"/vite/services/component.js\"]),\n      \"_ssr/[name].mjs\",\n    ],\n    [\"buildDir modules\", createChunk(\"build\", [\"/build/generated.js\"]), \"_build/[name].mjs\"],\n    [\n      \"mixed virtual + wasm\",\n      createChunk(\"mixed\", [\"\\0virtual:something\", \"/src/module.wasm\"]),\n      \"_wasm/[name].mjs\",\n    ],\n    [\"fallback to _chunks\", createChunk(\"misc\", [\"/src/utils/helper.ts\"]), \"_chunks/[name].mjs\"],\n  ])(\"%s → %s\", (_label, chunk, expected) => {\n    expect(getChunkName(chunk, nitro)).toBe(expected);\n  });\n\n  it(\"returns _routes/<path>.mjs for route handler\", () => {\n    const n = createNitro({\n      routing: {\n        routes: {\n          routes: [{ data: [{ route: \"/api/hello\", handler: \"/src/routes/api/hello.ts\" }] }],\n        },\n      },\n    } as any);\n    expect(getChunkName(createChunk(\"route\", [\"/src/routes/api/hello.ts\"]), n)).toBe(\n      \"_routes/api/hello.mjs\"\n    );\n  });\n\n  it(\"returns _routes/<path>.mjs for dynamic route\", () => {\n    const n = createNitro({\n      routing: {\n        routes: {\n          routes: [\n            {\n              data: [{ route: \"/api/users/:id\", handler: \"/src/routes/api/users/[id].ts\" }],\n            },\n          ],\n        },\n      },\n    } as any);\n    expect(getChunkName(createChunk(\"route\", [\"/src/routes/api/users/[id].ts\"]), n)).toBe(\n      \"_routes/api/users/[id].mjs\"\n    );\n  });\n\n  it(\"returns _routes/index.mjs for root route\", () => {\n    const n = createNitro({\n      routing: {\n        routes: {\n          routes: [{ data: [{ route: \"/\", handler: \"/src/routes/index.ts\" }] }],\n        },\n      },\n    } as any);\n    expect(getChunkName(createChunk(\"route\", [\"/src/routes/index.ts\"]), n)).toBe(\n      \"_routes/index.mjs\"\n    );\n  });\n\n  it(\"returns _tasks/[name].mjs for task handler\", () => {\n    const n = createNitro({\n      options: {\n        buildDir: \"/build\",\n        tasks: { \"db:migrate\": { handler: \"/src/tasks/migrate.ts\" } },\n      },\n    } as any);\n    expect(getChunkName(createChunk(\"task\", [\"/src/tasks/migrate.ts\"]), n)).toBe(\n      \"_tasks/[name].mjs\"\n    );\n  });\n});\n"
  },
  {
    "path": "test/unit/config-loader-env.test.ts",
    "content": "import { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"pathe\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\n\nvi.mock(\"nitro/meta\", () => ({\n  version: \"0.0.0-test\",\n  runtimeDir: \"/tmp\",\n  presetsDir: \"/tmp\",\n  pkgDir: \"/tmp\",\n  runtimeDependencies: [],\n}));\n\nconst originalNodeEnv = process.env.NODE_ENV;\nconst tempDirs: string[] = [];\n\nasync function createFixtureConfig() {\n  const rootDir = await mkdtemp(join(tmpdir(), \"nitro-config-env-\"));\n  tempDirs.push(rootDir);\n\n  await writeFile(\n    join(rootDir, \"nitro.config.ts\"),\n    `export default defineNitroConfig({\n  preset: 'node-server',\n  routeRules: {\n    '/base': { headers: { 'x-env': 'base' } }\n  },\n  $production: {\n    routeRules: {\n      '/prod': { headers: { 'x-env': 'production' } }\n    }\n  },\n  $development: {\n    routeRules: {\n      '/dev': { headers: { 'x-env': 'development' } }\n    }\n  }\n})\n`\n  );\n\n  return rootDir;\n}\n\nafterEach(async () => {\n  if (originalNodeEnv === undefined) {\n    delete process.env.NODE_ENV;\n  } else {\n    process.env.NODE_ENV = originalNodeEnv;\n  }\n\n  for (const dir of tempDirs.splice(0, tempDirs.length)) {\n    await rm(dir, { recursive: true, force: true });\n  }\n});\n\ndescribe.skip(\"config loader env layers\", () => {\n  it(\"applies $production when NODE_ENV is unset and dev=false\", async () => {\n    delete process.env.NODE_ENV;\n    const rootDir = await createFixtureConfig();\n\n    const { loadOptions } = await import(\"../../src/config/loader.ts\");\n    const options = await loadOptions({ rootDir, dev: false });\n\n    expect(options.routeRules[\"/prod\"]?.headers?.[\"x-env\"]).toBe(\"production\");\n    expect(options.routeRules[\"/dev\"]).toBeUndefined();\n    expect(options.routeRules[\"/base\"]?.headers?.[\"x-env\"]).toBe(\"base\");\n  });\n\n  it(\"applies $development when NODE_ENV is unset and dev=true\", async () => {\n    delete process.env.NODE_ENV;\n    const rootDir = await createFixtureConfig();\n\n    const { loadOptions } = await import(\"../../src/config/loader.ts\");\n    const options = await loadOptions({ rootDir, dev: true });\n\n    expect(options.routeRules[\"/dev\"]?.headers?.[\"x-env\"]).toBe(\"development\");\n    expect(options.routeRules[\"/prod\"]).toBeUndefined();\n    expect(options.routeRules[\"/base\"]?.headers?.[\"x-env\"]).toBe(\"base\");\n  });\n});\n"
  },
  {
    "path": "test/unit/runtime-config.env.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\n\nimport { applyEnv } from \"../../src/runtime/internal/runtime-config.ts\";\n\ndescribe(\"env utils\", () => {\n  describe(\"applyEnv\", () => {\n    const tests = [\n      {\n        config: { a: \"1\", b: \"2\" },\n        env: { NITRO_A: \"123\" },\n        expected: { a: \"123\", b: \"2\" },\n      },\n      {\n        config: { feature: { options: { option1: \"original\", option2: 123 } } },\n        env: { NITRO_FEATURE_OPTIONS_OPTION1: \"env\" },\n        expected: { feature: { options: { option1: \"env\", option2: 123 } } },\n      },\n    ];\n    for (const test of tests) {\n      it(`Config: ${JSON.stringify(test.config)} Env: { ${Object.entries(test.env)\n        .map(([key, value]) => `${key}=${JSON.stringify(value)}`)\n        .join(\" \")} }`, () => {\n        for (const key in test.env) {\n          process.env[key] = test.env[key as keyof typeof test.env] as string;\n        }\n        expect(applyEnv(test.config, { prefix: \"NITRO_\" })).toEqual(test.expected);\n        for (const key in test.env) {\n          delete process.env[key];\n        }\n      });\n    }\n  });\n\n  describe(\"envExpansion\", () => {\n    const tests = [\n      // envExpansion is false by default\n      {\n        config: { mail: \"{{MAIL_HOST}}:3366\" },\n        envOptions: {},\n        env: { MAIL_HOST: \"http://localhost\" },\n        expected: { mail: \"{{MAIL_HOST}}:3366\" },\n      },\n      // Fallback to the original string\n      {\n        config: { mail: \"{{MAIL_HOST}}:3366\" },\n        envOptions: { envExpansion: true },\n        env: {},\n        expected: { mail: \"{{MAIL_HOST}}:3366\" },\n      },\n      // Base usage\n      {\n        config: { mail: \"{{MAIL_HOST}}\" },\n        envOptions: { envExpansion: true },\n        env: { MAIL_HOST: \"http://localhost\" },\n        expected: { mail: \"http://localhost\" },\n      },\n      // With multiple envs\n      {\n        config: { mail: \"{{MAIL_SCHEME}}://{{MAIL_HOST}}:{{MAIL_PORT}}\" },\n        envOptions: { envExpansion: true },\n        env: { MAIL_SCHEME: \"http\", MAIL_HOST: \"localhost\", MAIL_PORT: \"3366\" },\n        expected: { mail: \"http://localhost:3366\" },\n      },\n    ];\n    for (const test of tests) {\n      it(`Config: ${JSON.stringify(test.config)} ${JSON.stringify(\n        test.envOptions\n      )} Env: { ${Object.entries(test.env)\n        .map(([key, value]) => `${key}=${JSON.stringify(value)}`)\n        .join(\" \")} }`, () => {\n        for (const key in test.env) {\n          process.env[key] = test.env[key as keyof typeof test.env];\n        }\n        expect(applyEnv(test.config, test.envOptions)).toEqual(test.expected);\n        for (const key in test.env) {\n          delete process.env[key];\n        }\n      });\n    }\n  });\n});\n"
  },
  {
    "path": "test/unit/runtime-config.test.ts",
    "content": "import { describe, expect, it, vi } from \"vitest\";\nimport { normalizeRuntimeConfig } from \"../../src/config/resolvers/runtime-config.ts\";\nimport type { NitroConfig } from \"nitro/types\";\n\nconst defaultRuntimeConfig = {\n  textProperty: \"value\",\n  numberProperty: 42,\n  booleanProperty: true,\n  arrayProperty: [\"A\", \"B\", \"C\"],\n  objectProperty: {\n    innerProperty: \"value\",\n  },\n  mixedArrayProperty: [\n    \"A\",\n    \"B\",\n    {\n      inner: {\n        innerProperty: \"value\",\n      },\n    },\n  ],\n};\n\nconst nitroConfig: NitroConfig = {\n  runtimeConfig: defaultRuntimeConfig,\n  baseURL: \"https://example.com\",\n  experimental: {\n    envExpansion: false,\n  },\n};\n\ndescribe(\"normalizeRuntimeConfig\", () => {\n  it(\"should not warn on a serializable runtime config\", () => {\n    const warnSpy = vi.spyOn(console, \"warn\");\n    normalizeRuntimeConfig(nitroConfig);\n    expect(warnSpy).not.toHaveBeenCalled();\n  });\n\n  it(\"should not warn when primitive prototype is changed\", () => {\n    const warnSpy = vi.spyOn(console, \"warn\");\n\n    // https://github.com/nitrojs/nitro/pull/2902\n    (String.prototype as any).brokenFunction = () => undefined;\n\n    normalizeRuntimeConfig(nitroConfig);\n    expect(warnSpy).not.toHaveBeenCalled();\n\n    delete (String.prototype as any).brokenFunction;\n  });\n\n  it(\"should throw a warning when runtimeConfig is not serializable\", () => {\n    // const originalWarn = console.warn;\n    const spyWarn = (console.warn = vi.fn());\n    normalizeRuntimeConfig({\n      ...nitroConfig,\n      runtimeConfig: {\n        ...defaultRuntimeConfig,\n        brokenProperty: new Map(),\n      },\n    });\n    console.warn = spyWarn;\n    expect(spyWarn).toHaveBeenCalledOnce();\n  });\n});\n"
  },
  {
    "path": "test/unit/sourcemap-min.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\nimport { sourcemapMinify } from \"../../src/build/plugins/sourcemap-min.ts\";\n\ntype BundleAsset = { type: \"asset\"; source: string };\n\nfunction createSourcemapAsset(sourcemap: {\n  sources?: string[];\n  sourcesContent?: string[];\n  mappings?: string;\n  x_google_ignoreList?: number[];\n}): BundleAsset {\n  return {\n    type: \"asset\",\n    source: JSON.stringify({\n      version: 3,\n      sources: [],\n      mappings: \"AAAA,CAAC\",\n      ...sourcemap,\n    }),\n  };\n}\n\nfunction runPlugin(bundle: Record<string, BundleAsset>) {\n  const plugin = sourcemapMinify();\n  (plugin.generateBundle as Function).call(null, {}, bundle);\n  const results: Record<string, ReturnType<typeof JSON.parse>> = {};\n  for (const [key, asset] of Object.entries(bundle)) {\n    if (key.endsWith(\".map\")) {\n      results[key] = JSON.parse(asset.source);\n    }\n  }\n  return results;\n}\n\ndescribe(\"sourcemapMinify\", () => {\n  it(\"removes sourcesContent from all sourcemaps\", () => {\n    const bundle = {\n      \"index.mjs.map\": createSourcemapAsset({\n        sources: [\"src/index.ts\"],\n        sourcesContent: [\"export default 42;\"],\n      }),\n    };\n    const results = runPlugin(bundle);\n    expect(results[\"index.mjs.map\"].sourcesContent).toBeUndefined();\n  });\n\n  it(\"removes x_google_ignoreList from all sourcemaps\", () => {\n    const bundle = {\n      \"index.mjs.map\": createSourcemapAsset({\n        sources: [\"src/index.ts\"],\n        x_google_ignoreList: [0],\n      }),\n    };\n    const results = runPlugin(bundle);\n    expect(results[\"index.mjs.map\"].x_google_ignoreList).toBeUndefined();\n  });\n\n  it(\"wipes mappings for pure library chunks\", () => {\n    const bundle = {\n      \"_libs/express.mjs.map\": createSourcemapAsset({\n        sources: [\n          \"../../node_modules/express/index.js\",\n          \"../../node_modules/express/lib/router.js\",\n        ],\n        mappings: \"AAAA,CAAC\",\n      }),\n    };\n    const results = runPlugin(bundle);\n    expect(results[\"_libs/express.mjs.map\"].mappings).toBe(\"\");\n  });\n\n  it(\"preserves mappings for pure user code chunks\", () => {\n    const bundle = {\n      \"_routes/api/hello.mjs.map\": createSourcemapAsset({\n        sources: [\"src/routes/api/hello.ts\"],\n        mappings: \"AAAA,CAAC\",\n      }),\n    };\n    const results = runPlugin(bundle);\n    expect(results[\"_routes/api/hello.mjs.map\"].mappings).toBe(\"AAAA,CAAC\");\n  });\n\n  it(\"preserves mappings when library is hoisted into user chunk\", () => {\n    const bundle = {\n      \"_routes/api/hello.mjs.map\": createSourcemapAsset({\n        sources: [\"src/routes/api/hello.ts\", \"../../node_modules/some-lib/index.js\"],\n        mappings: \"AAAA,CAAC\",\n      }),\n    };\n    const results = runPlugin(bundle);\n    expect(results[\"_routes/api/hello.mjs.map\"].mappings).toBe(\"AAAA,CAAC\");\n  });\n\n  it(\"skips non-sourcemap files\", () => {\n    const bundle = {\n      \"index.mjs\": { type: \"asset\" as const, source: \"console.log(42)\" },\n    };\n    runPlugin(bundle as any);\n    expect(bundle[\"index.mjs\"].source).toBe(\"console.log(42)\");\n  });\n\n  it(\"handles empty sources array\", () => {\n    const bundle = {\n      \"chunk.mjs.map\": createSourcemapAsset({\n        sources: [],\n        mappings: \"AAAA,CAAC\",\n      }),\n    };\n    const results = runPlugin(bundle);\n    expect(results[\"chunk.mjs.map\"].mappings).toBe(\"\");\n  });\n});\n"
  },
  {
    "path": "test/unit/static-middleware.test.ts",
    "content": "import { beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { mockEvent } from \"h3\";\nimport handler from \"../../src/runtime/internal/static.ts\";\n\nconst { getAsset, isPublicAssetURL, readAsset } = vi.hoisted(() => ({\n  getAsset: vi.fn(),\n  isPublicAssetURL: vi.fn(),\n  readAsset: vi.fn(),\n}));\n\nvi.mock(\"#nitro/virtual/public-assets\", () => ({\n  getAsset,\n  isPublicAssetURL,\n  readAsset,\n}));\n\nfunction createEvent(pathname: string, acceptEncoding = \"\") {\n  const event = mockEvent(`http://localhost${pathname}`, {\n    headers: acceptEncoding ? { \"accept-encoding\": acceptEncoding } : undefined,\n  });\n  event.res.headers.set(\"Vary\", \"Origin\");\n  event.res.headers.set(\"Cache-Control\", \"max-age=3600\");\n  return event;\n}\n\ndescribe(\"runtime static middleware\", () => {\n  beforeEach(() => {\n    getAsset.mockReset();\n    isPublicAssetURL.mockReset();\n    readAsset.mockReset();\n  });\n\n  it(\"does not append Accept-Encoding vary when no asset is matched\", async () => {\n    getAsset.mockReturnValue(undefined);\n    isPublicAssetURL.mockReturnValue(true);\n    const event = createEvent(\"/foo-missing.css\", \"gzip\");\n\n    expect(() => handler(event)).toThrow(\"404\");\n    expect(event.res.headers.get(\"Vary\")).toBe(\"Origin\");\n    expect(event.res.headers.get(\"Cache-Control\")).toBeNull();\n  });\n\n  it(\"appends Accept-Encoding vary when a compressed asset is matched\", async () => {\n    getAsset.mockImplementation((id: string) => {\n      if (id === \"/foo.css.gz\") {\n        return {\n          etag: '\"test\"',\n          mtime: Date.now(),\n          type: \"text/css\",\n          encoding: \"gzip\",\n          size: 1,\n        };\n      }\n      return undefined;\n    });\n    isPublicAssetURL.mockReturnValue(true);\n    readAsset.mockResolvedValue(\"body\");\n    const event = createEvent(\"/foo.css\", \"gzip\");\n\n    await handler(event);\n\n    expect(event.res.headers.get(\"Vary\")).toContain(\"Origin\");\n    expect(event.res.headers.get(\"Vary\")).toContain(\"Accept-Encoding\");\n  });\n});\n"
  },
  {
    "path": "test/unit/virtual.test.ts",
    "content": "import { describe, expect, it } from \"vitest\";\n\nimport { serverFetch } from \"nitro/app\";\n\ndescribe(\"virtual modules\", () => {\n  it(\"app fetch\", async () => {\n    const res = await serverFetch(\"/\");\n    expect(res.status).toBe(404);\n    expect(await res.text()).to.include(\"Cannot find any route matching\");\n  });\n});\n"
  },
  {
    "path": "test/unit/zephyr-preset.test.ts",
    "content": "import { afterEach, describe, expect, it, vi } from \"vitest\";\n\nconst ZEPHYR_PRESET_PATH = \"../../src/presets/zephyr/preset.ts\";\n\nconst importDepMock = vi.hoisted(() => vi.fn());\nvi.mock(\"../../src/utils/dep.ts\", () => ({\n  importDep: importDepMock,\n}));\n\nasync function getZephyrPreset() {\n  const { default: presets } = await import(ZEPHYR_PRESET_PATH);\n  return presets[0];\n}\n\ndescribe(\"zephyr preset\", () => {\n  afterEach(() => {\n    vi.restoreAllMocks();\n    vi.clearAllMocks();\n    vi.resetModules();\n    delete (globalThis as any).__nitroDeploying__;\n    delete process.env.NITRO_INTERNAL_ZEPHYR_SKIP_DEPLOY_ON_BUILD;\n  });\n\n  it(\"extends base-worker\", async () => {\n    const preset = await getZephyrPreset();\n    expect(preset.extends).toBe(\"base-worker\");\n    expect(preset.output?.publicDir).toBe(\"{{ output.dir }}/client/{{ baseURL }}\");\n    expect(preset.commands?.deploy).toBeUndefined();\n  });\n\n  it(\"adds cloudflare unenv presets\", async () => {\n    const preset = await getZephyrPreset();\n    const hooks = preset.hooks!;\n\n    const nitro = {\n      options: {\n        preset: \"zephyr\",\n        output: {\n          dir: \"/tmp/zephyr-output\",\n          serverDir: \"/tmp/zephyr-output/server\",\n        },\n        unenv: [],\n      },\n      logger: {\n        info: vi.fn(),\n        success: vi.fn(),\n      },\n    } as any;\n\n    await hooks[\"build:before\"]?.(nitro);\n    expect(nitro.options.unenv).toHaveLength(2);\n    expect(nitro.options.unenv[0].meta?.name).toBe(\"nitro:cloudflare-externals\");\n    expect(nitro.options.unenv[1].meta?.name).toBe(\"nitro:cloudflare-node-compat\");\n    expect(nitro.logger.info).not.toHaveBeenCalled();\n    expect(nitro.logger.success).not.toHaveBeenCalled();\n  });\n\n  it(\"deploys on compiled hook by default\", async () => {\n    const uploadOutputToZephyr = vi.fn().mockResolvedValue({\n      deploymentUrl: \"https://example.zephyr-cloud.io\",\n      entrypoint: \"server/index.mjs\",\n    });\n    importDepMock.mockResolvedValue({ uploadOutputToZephyr });\n\n    (globalThis as any).__nitroDeploying__ = true;\n\n    const preset = await getZephyrPreset();\n\n    const hooks = preset.hooks!;\n    const nitro = {\n      options: {\n        rootDir: \"/tmp/project\",\n        baseURL: \"/docs/\",\n        output: {\n          dir: \"/tmp/zephyr-output\",\n          publicDir: \"client/docs\",\n        },\n      },\n      logger: {\n        info: vi.fn(),\n        success: vi.fn(),\n      },\n    } as any;\n\n    await hooks.compiled?.(nitro);\n\n    expect(importDepMock).toHaveBeenCalledWith({\n      id: \"zephyr-agent\",\n      reason: \"deploying to Zephyr\",\n      dir: \"/tmp/project\",\n    });\n    expect(uploadOutputToZephyr).toHaveBeenCalledWith({\n      rootDir: \"/tmp/project\",\n      baseURL: \"/docs/\",\n      outputDir: \"/tmp/zephyr-output\",\n      publicDir: \"/tmp/zephyr-output/client/docs\",\n    });\n    expect(nitro.logger.success).toHaveBeenCalledWith(\n      \"[zephyr-nitro-preset] Zephyr deployment succeeded: https://example.zephyr-cloud.io\"\n    );\n    expect(nitro.logger.info).not.toHaveBeenCalled();\n  });\n\n  it(\"can skip deploy on build\", async () => {\n    const uploadOutputToZephyr = vi.fn().mockResolvedValue({\n      deploymentUrl: \"https://example.zephyr-cloud.io\",\n      entrypoint: \"server/index.mjs\",\n    });\n    importDepMock.mockResolvedValue({ uploadOutputToZephyr });\n\n    const preset = await getZephyrPreset();\n    const hooks = preset.hooks!;\n    const nitro = {\n      options: {\n        zephyr: {\n          deployOnBuild: false,\n        },\n        output: {\n          dir: \"/tmp/zephyr-output\",\n        },\n      },\n      logger: {\n        info: vi.fn(),\n        success: vi.fn(),\n      },\n    } as any;\n\n    await hooks.compiled?.(nitro);\n\n    expect(importDepMock).not.toHaveBeenCalled();\n    expect(uploadOutputToZephyr).not.toHaveBeenCalled();\n    expect(nitro.logger.info).toHaveBeenCalledWith(\n      \"[zephyr-nitro-preset] Zephyr deploy skipped on build.\"\n    );\n    expect(nitro.logger.success).not.toHaveBeenCalled();\n  });\n});\n"
  },
  {
    "path": "test/vite/hmr-fixture/api/state.ts",
    "content": "import { state } from \"../shared.ts\";\n\nexport default () => ({ state });\n"
  },
  {
    "path": "test/vite/hmr-fixture/app/entry-client.ts",
    "content": "import { state } from \"../shared.ts\";\n\ndocument.getElementById(\"client-state-value\")!.textContent = state + \" (modified)\";\n"
  },
  {
    "path": "test/vite/hmr-fixture/app/entry-server.ts",
    "content": "import { html } from \"nitro/h3\";\nimport { serverFetch } from \"nitro\";\nimport { state } from \"../shared.ts\";\n\nexport default {\n  fetch: async () => {\n    const apiData = (await serverFetch(\"/api/state\").then((res) => res.json())) as {\n      state: number;\n    };\n    const viteClientScript = \"<script type='module' src='/@vite/client'></script>\";\n    const clientScript = \"<script type='module' src='/app/entry-client.ts'></script>\";\n    return html`\n    <!doctype html>\n    <html lang=\"en\">\n      <head>${viteClientScript}</head>\n      <body>\n        <h1>SSR Page</h1>\n        <p>[SSR] state: ${state}</p>\n        <p>[API] state: ${apiData.state}</p>\n        <p id=\"client-state\">[Client] state: <span id=\"client-state-value\">?</span></p>\n        ${clientScript}\n      </body>\n    </html>\n  `;\n  },\n};\n"
  },
  {
    "path": "test/vite/hmr-fixture/shared.ts",
    "content": "export const state = 1;\n"
  },
  {
    "path": "test/vite/hmr-fixture/tsconfig.json",
    "content": "{\n  \"extends\": \"nitro/tsconfig\"\n}\n"
  },
  {
    "path": "test/vite/hmr-fixture/vite.config.ts",
    "content": "import { defineConfig } from \"vite\";\nimport { nitro } from \"nitro/vite\";\n\nexport default defineConfig({\n  plugins: [nitro({ serverDir: \"./\" })],\n});\n"
  },
  {
    "path": "test/vite/hmr.test.ts",
    "content": "import { join } from \"pathe\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ViteDevServer } from \"vite\";\nimport { describe, test, expect, beforeAll, afterEach, afterAll } from \"vitest\";\n\nconst { createServer } = (await import(\n  process.env.NITRO_VITE_PKG || \"vite\"\n)) as typeof import(\"vite\");\n\ndescribe(\"vite:hmr\", { sequential: true }, () => {\n  let server: ViteDevServer;\n  let serverURL: string;\n  const wsMessages: any[] = [];\n\n  const rootDir = fileURLToPath(new URL(\"./hmr-fixture\", import.meta.url));\n\n  const files = {\n    client: openFileForEditing(join(rootDir, \"app/entry-client.ts\")),\n    api: openFileForEditing(join(rootDir, \"api/state.ts\")),\n    shared: openFileForEditing(join(rootDir, \"shared.ts\")),\n    ssr: openFileForEditing(join(rootDir, \"app/entry-server.ts\")),\n  };\n\n  beforeAll(async () => {\n    process.chdir(rootDir);\n    server = await createServer({ root: rootDir });\n\n    const originalSend = server.ws.send.bind(server.ws);\n    server.ws.send = function (payload: any) {\n      wsMessages.push(payload);\n      return originalSend(payload);\n    };\n\n    await server.listen(\"0\" as unknown as number);\n    const addr = server.httpServer?.address() as { port: number; address: string; family: string };\n    serverURL = `http://${addr.family === \"IPv6\" ? `[${addr.address}]` : addr.address}:${addr.port}`;\n\n    const html = await fetch(serverURL).then((r) => r.text());\n    expect(html).toContain(\"<h1>SSR Page</h1>\");\n    expect(html).toContain(\"[SSR] state: 1\");\n    expect(html).toContain(\"[API] state: 1\");\n  }, 30_000);\n\n  afterAll(async () => {\n    await server?.close();\n  });\n\n  afterEach(async () => {\n    wsMessages.length = 0;\n    let restored = false;\n    for (const file of Object.values(files)) {\n      if (file.restore()) {\n        restored = true;\n      }\n    }\n    if (restored) {\n      await waitFor(() => wsMessages.length > 0, 500);\n    }\n    wsMessages.length = 0;\n  });\n\n  test(\"editing API entry\", async () => {\n    files.api.update((content) =>\n      content.replace(\"({ state })\", '({ state: state + \" (modified)\" })')\n    );\n    await pollResponse(`${serverURL}/api/state`, /modified/);\n    expect(wsMessages).toMatchObject([{ type: \"full-reload\" }]);\n  });\n\n  test(\"Editing client entry (no full-reload)\", async () => {\n    files.client.update((content) => content.replace(`+ \"\"`, `+ \" (modified)\"`));\n    await pollResponse(`${serverURL}/app/entry-client.ts`, /modified/);\n    expect(wsMessages.length).toBe(0);\n  });\n\n  test(\"editing SSR entry (no full-reload)\", async () => {\n    files.ssr.update((content) =>\n      content.replace(\"<h1>SSR Page</h1>\", \"<h1>Modified SSR Page</h1>\")\n    );\n    await pollResponse(serverURL, /Modified SSR Page/);\n    expect(wsMessages.length).toBe(0);\n  });\n\n  test(\"Editing shared entry\", async () => {\n    files.shared.update((content) => content.replace(`state = 1`, `state = 2`));\n    await pollResponse(\n      `${serverURL}`,\n      (txt) => txt.includes(\"state: 2\") && !txt.includes(\"state: 1\")\n    );\n    expect(wsMessages).toMatchObject([{ type: \"full-reload\" }]);\n  });\n});\n\nfunction openFileForEditing(path: string) {\n  const originalContent = readFileSync(path, \"utf-8\");\n  return {\n    path,\n    update(cb: (content: string) => string) {\n      const currentContent = readFileSync(path, \"utf-8\");\n      const newContent = cb(currentContent);\n      writeFileSync(path, newContent);\n    },\n    restore() {\n      if (readFileSync(path, \"utf-8\") !== originalContent) {\n        writeFileSync(path, originalContent);\n        return true;\n      }\n      return false;\n    },\n  };\n}\n\nfunction waitFor(check: () => boolean, duration: number): Promise<void> {\n  const start = Date.now();\n  return new Promise((resolve) => {\n    const poll = () => {\n      if (check() || Date.now() - start > duration) {\n        resolve();\n      } else {\n        setTimeout(poll, 10);\n      }\n    };\n    poll();\n  });\n}\n\nfunction pollResponse(\n  url: string,\n  match: RegExp | ((txt: string) => boolean),\n  timeout = 5000\n): Promise<string> {\n  const start = Date.now();\n  let lastResponse = \"\";\n  return new Promise((resolve, reject) => {\n    const check = async () => {\n      try {\n        const response = await fetch(url);\n        lastResponse = await response.text();\n        if (typeof match === \"function\" ? match(lastResponse) : match.test(lastResponse)) {\n          resolve(lastResponse);\n        } else if (Date.now() - start > timeout) {\n          reject(\n            new Error(\n              `Timeout waiting for response to match ${match} at ${url}. Last response: ${lastResponse}`\n            )\n          );\n        } else {\n          setTimeout(check, 100);\n        }\n      } catch (err) {\n        reject(err);\n      }\n    };\n    check();\n  });\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"extends\": \"./lib/tsconfig.json\",\n  \"compilerOptions\": {\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"allowSyntheticDefaultImports\": true,\n    \"erasableSyntaxOnly\": true,\n    \"noUncheckedIndexedAccess\": false,\n    \"noImplicitReturns\": false,\n    \"jsx\": \"preserve\",\n    \"lib\": [\"es2022\", \"webworker\", \"dom.iterable\"],\n    \"types\": [\"node\", \"@cloudflare/workers-types\"]\n  },\n  \"exclude\": [\n    \"examples/import-alias/**\",\n    \"examples/vite-rsc/**\",\n    \"test/fixture/server/routes/jsx.tsx\",\n    \"examples/vite-ssr-html/vite.config.ts\",\n    \"examples/vite-ssr-solid/src/entry-server.tsx\",\n    \"examples/vite-ssr-solid/src/entry-client.tsx\"\n  ]\n}\n"
  },
  {
    "path": "vitest.config.ts",
    "content": "import { defineConfig } from \"vitest/config\";\n\nprocess.env.NODE_ENV = \"production\";\n\nexport default defineConfig({\n  test: {\n    testTimeout: 30_000,\n    coverage: {\n      reporter: [\"text\", \"clover\", \"json\"],\n      include: [\"src/**/*.ts\", \"!src/types/**/*.ts\"],\n    },\n    include: [\"test/**/*.test.ts\"],\n  },\n});\n"
  }
]