├── .github
├── CODEOWNERS
├── codecov.yml
├── ISSUE_TEMPLATE
│ ├── config.yml
│ └── feature-request.yml
├── workflows-disabled
│ └── codeql.yml
└── workflows
│ └── autofix.yml
├── test
├── fixture
│ ├── public
│ │ ├── foo.css
│ │ ├── build
│ │ │ └── test.txt
│ │ ├── foo.js
│ │ ├── _ignored.txt
│ │ ├── _unignored.txt
│ │ ├── favicon.ico
│ │ └── cf-pages-exclude
│ │ │ └── not-in-routes-json.txt
│ ├── files
│ │ ├── sql.sql
│ │ ├── sqlts.sql.ts
│ │ ├── index.html
│ │ └── test.txt
│ ├── .gitignore
│ ├── assets
│ │ ├── test.json
│ │ ├── test.md
│ │ └── cat.jpg
│ ├── .env
│ ├── utils
│ │ ├── test.ts
│ │ └── foo
│ │ │ ├── test.ts
│ │ │ └── bar
│ │ │ └── test.ts
│ ├── wrangler.toml
│ ├── api
│ │ ├── hey
│ │ │ └── index.get.ts
│ │ ├── methods
│ │ │ ├── get.ts
│ │ │ ├── foo.get.get.ts
│ │ │ ├── index.get.ts
│ │ │ ├── index.post.ts
│ │ │ ├── default.ts
│ │ │ └── default.post.ts
│ │ ├── serialized
│ │ │ ├── void.ts
│ │ │ ├── null.ts
│ │ │ ├── date.ts
│ │ │ ├── function.ts
│ │ │ ├── set.ts
│ │ │ ├── tuple.ts
│ │ │ ├── error.ts
│ │ │ └── map.ts
│ │ ├── hello.ts
│ │ ├── kebab.ts
│ │ ├── upload.post.ts
│ │ ├── _ignored.ts
│ │ ├── typed
│ │ │ ├── todos
│ │ │ │ ├── [...].ts
│ │ │ │ └── [todoId]
│ │ │ │ │ └── comments
│ │ │ │ │ └── [...commentId].ts
│ │ │ ├── user
│ │ │ │ ├── john
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── [johnExtends].ts
│ │ │ │ │ └── post
│ │ │ │ │ │ ├── [postId].ts
│ │ │ │ │ │ └── coffee.ts
│ │ │ │ └── [userId]
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── [userExtends].ts
│ │ │ │ │ └── post
│ │ │ │ │ ├── [postId].ts
│ │ │ │ │ └── firstPost.ts
│ │ │ └── catchall
│ │ │ │ ├── some
│ │ │ │ └── [...test].ts
│ │ │ │ └── [slug]
│ │ │ │ └── [...another].ts
│ │ ├── wildcard
│ │ │ └── [...param].ts
│ │ ├── param
│ │ │ └── [test-id].ts
│ │ ├── storage
│ │ │ ├── dev.dev.ts
│ │ │ ├── item.put.ts
│ │ │ └── item.get.ts
│ │ ├── echo.ts
│ │ ├── error.ts
│ │ ├── cached.ts
│ │ ├── errors.ts
│ │ ├── headers.ts
│ │ ├── db.ts
│ │ └── meta
│ │ │ └── test.ts
│ ├── app.config.ts
│ ├── routes
│ │ ├── env
│ │ │ ├── index.dev.ts
│ │ │ └── index.get.prod.ts
│ │ ├── rules
│ │ │ └── [...slug].ts
│ │ ├── json-string.ts
│ │ ├── (route-group)
│ │ │ └── route-group.ts
│ │ ├── 500.ts
│ │ ├── error-stack.ts
│ │ ├── imports.ts
│ │ ├── assets
│ │ │ ├── md.ts
│ │ │ ├── all.ts
│ │ │ └── [id].ts
│ │ ├── config.ts
│ │ ├── wasm
│ │ │ ├── static-import.ts
│ │ │ └── dynamic-import.ts
│ │ ├── context.ts
│ │ ├── tasks
│ │ │ └── [...name].ts
│ │ ├── raw.ts
│ │ ├── file.ts
│ │ ├── jsx.tsx
│ │ ├── wait-until.ts
│ │ ├── stream.ts
│ │ ├── fetch.ts
│ │ ├── prerender-custom.html.ts
│ │ ├── static-flags.ts
│ │ ├── modules.ts
│ │ └── icon.png.ts
│ ├── server.config.ts
│ ├── node_modules
│ │ └── @fixture
│ │ │ ├── nitro-utils
│ │ │ ├── index.mjs
│ │ │ ├── extra.mjs
│ │ │ ├── extra2.mjs
│ │ │ └── package.json
│ │ │ ├── nitro-lib
│ │ │ ├── subpath.mjs
│ │ │ ├── node_modules
│ │ │ │ └── @fixture
│ │ │ │ │ └── nested-lib
│ │ │ │ │ ├── index.mjs
│ │ │ │ │ └── package.json
│ │ │ ├── index.mjs
│ │ │ └── package.json
│ │ │ ├── nitro-dep-a
│ │ │ ├── index.mjs
│ │ │ ├── node_modules
│ │ │ │ └── @fixture
│ │ │ │ │ └── nitro-lib
│ │ │ │ │ ├── node_modules
│ │ │ │ │ └── @fixture
│ │ │ │ │ │ └── nested-lib
│ │ │ │ │ │ ├── index.mjs
│ │ │ │ │ │ └── package.json
│ │ │ │ │ ├── index.mjs
│ │ │ │ │ └── package.json
│ │ │ └── package.json
│ │ │ └── nitro-dep-b
│ │ │ ├── index.mjs
│ │ │ ├── node_modules
│ │ │ └── @fixture
│ │ │ │ └── nitro-lib
│ │ │ │ ├── subpath.mjs
│ │ │ │ ├── node_modules
│ │ │ │ └── @fixture
│ │ │ │ │ └── nested-lib
│ │ │ │ │ ├── index.mjs
│ │ │ │ │ └── package.json
│ │ │ │ ├── index.mjs
│ │ │ │ └── package.json
│ │ │ └── package.json
│ ├── middleware
│ │ └── _ignored.ts
│ ├── plugins
│ │ ├── errors.ts
│ │ └── vary.ts
│ ├── tasks
│ │ ├── db
│ │ │ └── migrate.ts
│ │ └── test.ts
│ ├── error.ts
│ └── tsconfig.json
├── presets
│ ├── static.test.ts
│ ├── bun.test.ts
│ ├── deno-server.test.ts
│ ├── winterjs.test.ts
│ ├── cloudflare-module.test.ts
│ └── node.test.ts
└── scripts
│ └── gen-fixture-types.ts
├── src
├── runtime
│ ├── internal
│ │ ├── empty.ts
│ │ ├── meta.ts
│ │ ├── plugin.ts
│ │ ├── debug.ts
│ │ ├── client.ts
│ │ ├── error
│ │ │ └── utils.ts
│ │ ├── storage.ts
│ │ ├── database.ts
│ │ ├── index.ts
│ │ ├── context.ts
│ │ ├── shutdown.ts
│ │ └── routes
│ │ │ └── swagger.ts
│ └── index.ts
├── types
│ ├── virtual
│ │ ├── polyfills.ts
│ │ ├── app-config.d.ts
│ │ ├── storage.d.ts
│ │ ├── plugins.d.ts
│ │ ├── server-assets.d.ts
│ │ ├── database.d.ts
│ │ ├── server-handlers-meta.d.ts
│ │ ├── tasks.ts
│ │ ├── error-handler.d.ts
│ │ ├── public-assets.d.ts
│ │ └── server-handlers.d.ts
│ ├── fetch
│ │ └── index.ts
│ ├── runtime
│ │ ├── index.ts
│ │ ├── asset.ts
│ │ ├── task.ts
│ │ └── cache.ts
│ ├── module.ts
│ ├── index.ts
│ ├── preset.ts
│ ├── prerender.ts
│ ├── global.ts
│ ├── _utils.ts
│ ├── dev.ts
│ ├── h3.ts
│ ├── hooks.ts
│ └── openapi.ts
├── presets
│ ├── index.mjs
│ ├── aws-lambda
│ │ ├── types.ts
│ │ └── preset.ts
│ ├── index.ts
│ ├── _nitro
│ │ ├── preset.ts
│ │ ├── runtime
│ │ │ ├── nitro-prerenderer.ts
│ │ │ └── service-worker.ts
│ │ ├── nitro-prerender.ts
│ │ ├── nitro-dev.ts
│ │ └── base-worker.ts
│ ├── genezio
│ │ └── preset.ts
│ ├── azure
│ │ ├── types.ts
│ │ ├── preset.ts
│ │ └── runtime
│ │ │ └── azure-swa.ts
│ ├── koyeb
│ │ └── preset.ts
│ ├── netlify
│ │ ├── types.ts
│ │ └── runtime
│ │ │ └── netlify-edge.ts
│ ├── heroku
│ │ └── preset.ts
│ ├── render.com
│ │ └── preset.ts
│ ├── platform.sh
│ │ └── preset.ts
│ ├── cleavr
│ │ └── preset.ts
│ ├── digitalocean
│ │ └── preset.ts
│ ├── flightcontrol
│ │ └── preset.ts
│ ├── zeabur
│ │ └── runtime
│ │ │ └── zeabur.ts
│ ├── stormkit
│ │ ├── preset.ts
│ │ └── runtime
│ │ │ └── stormkit.ts
│ ├── alwaysdata
│ │ └── preset.ts
│ ├── bun
│ │ ├── preset.ts
│ │ └── runtime
│ │ │ └── bun.ts
│ ├── cloudflare
│ │ ├── wrangler
│ │ │ └── _utils.ts
│ │ └── runtime
│ │ │ └── cloudflare-module.ts
│ ├── aws-amplify
│ │ ├── runtime
│ │ │ └── aws-amplify.ts
│ │ └── preset.ts
│ ├── _utils
│ │ ├── preset.ts
│ │ └── fs.ts
│ ├── winterjs
│ │ └── preset.ts
│ ├── vercel
│ │ ├── runtime
│ │ │ └── vercel.ts
│ │ └── preset.ts
│ ├── node
│ │ ├── runtime
│ │ │ ├── node-middleware.ts
│ │ │ └── cli.ts
│ │ └── preset.ts
│ ├── zerops
│ │ └── preset.ts
│ ├── _unenv
│ │ ├── preset-deno.ts
│ │ └── workerd
│ │ │ ├── console.mjs
│ │ │ └── tls.mjs
│ ├── iis
│ │ └── preset.ts
│ ├── deno
│ │ └── runtime
│ │ │ └── deno-deploy.ts
│ ├── _static
│ │ └── preset.ts
│ ├── _all.gen.ts
│ └── firebase
│ │ └── preset.ts
├── config
│ ├── resolvers
│ │ ├── url.ts
│ │ ├── error.ts
│ │ ├── builder.ts
│ │ ├── database.ts
│ │ ├── storage.ts
│ │ ├── compatibility.ts
│ │ ├── export-conditions.ts
│ │ └── unenv.ts
│ └── update.ts
├── utils
│ ├── nitro.ts
│ ├── parallel.ts
│ └── storage.ts
├── cli
│ ├── common.ts
│ ├── commands
│ │ ├── task
│ │ │ ├── index.ts
│ │ │ ├── list.ts
│ │ │ └── run.ts
│ │ ├── prepare.ts
│ │ └── build.ts
│ └── index.ts
├── build
│ ├── plugins
│ │ ├── server-main.ts
│ │ ├── replace.ts
│ │ ├── sourcemap-min.ts
│ │ ├── error-handler.ts
│ │ ├── database.ts
│ │ └── virtual.ts
│ ├── rollup
│ │ ├── build.ts
│ │ └── error.ts
│ ├── build.ts
│ ├── rolldown
│ │ └── build.ts
│ ├── prepare.ts
│ └── snapshot.ts
├── index.ts
├── module.ts
└── dev
│ └── proxy.ts
├── .gitattributes
├── playground
├── public
│ └── test.txt
├── tsconfig.json
├── server
│ └── routes
│ │ └── index.ts
└── nitro.config.ts
├── .prettierrc
├── pnpm-workspace.yaml
├── docs
├── 2.deploy
│ ├── 10.runtimes
│ │ ├── _dir.yml
│ │ ├── bun.md
│ │ ├── deno.md
│ │ └── _winterjs.md
│ └── 20.providers
│ │ ├── _dir.yml
│ │ ├── zeabur.md
│ │ ├── cleavr.md
│ │ ├── stormkit.md
│ │ ├── gitlab-pages.md
│ │ ├── platform-sh.md
│ │ ├── firebase.md
│ │ ├── render.md
│ │ ├── edgio.md
│ │ ├── aws.md
│ │ ├── iis.md
│ │ └── digitalocean.md
├── bun.lockb
├── .config
│ └── automd.config.ts
├── .docs
│ └── public
│ │ └── images
│ │ ├── stormkit-deploy.png
│ │ └── stormkit-new-app.png
├── package.json
└── 1.guide
│ ├── 99.nightly.md
│ └── 98.typescript.md
├── .npmrc
├── renovate.json
├── examples
├── api-routes
│ ├── tsconfig.json
│ ├── api
│ │ ├── hello.ts
│ │ ├── test.get.ts
│ │ ├── hello
│ │ │ └── [name].ts
│ │ └── test.post.ts
│ ├── nitro.config.ts
│ ├── package.json
│ └── routes
│ │ └── [...].ts
├── database
│ ├── tsconfig.json
│ ├── nitro.config.ts
│ ├── package.json
│ ├── tasks
│ │ └── db
│ │ │ └── migrate.ts
│ └── routes
│ │ └── index.ts
├── middleware
│ ├── tsconfig.json
│ ├── nitro.config.ts
│ ├── routes
│ │ └── index.ts
│ ├── middleware
│ │ └── auth.ts
│ └── package.json
├── plugins
│ ├── tsconfig.json
│ ├── plugins
│ │ └── test.ts
│ ├── routes
│ │ └── index.ts
│ ├── nitro.config.ts
│ └── package.json
├── renderer
│ ├── tsconfig.json
│ ├── api
│ │ └── hello.ts
│ ├── nitro.config.ts
│ ├── package.json
│ └── renderer.ts
├── websocket
│ ├── tsconfig.json
│ ├── nitro.config.ts
│ ├── package.json
│ └── routes
│ │ └── _ws.ts
├── auto-imports
│ ├── tsconfig.json
│ ├── nitro.config.ts
│ ├── routes
│ │ └── index.ts
│ ├── utils
│ │ └── hello.ts
│ └── package.json
├── cached-handler
│ ├── tsconfig.json
│ ├── nitro.config.ts
│ ├── package.json
│ └── routes
│ │ └── index.ts
├── tsconfig.json
├── custom-error-handler
│ ├── tsconfig.json
│ ├── routes
│ │ └── index.ts
│ ├── nitro.config.ts
│ ├── error.ts
│ └── package.json
├── graceful-shutdown
│ ├── tsconfig.json
│ ├── nitro.config.ts
│ ├── package.json
│ ├── routes
│ │ └── index.ts
│ └── plugins
│ │ └── db.ts
├── hello-world
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── README.md
│ ├── server
│ │ └── routes
│ │ │ └── index.ts
│ ├── nitro.config.ts
│ └── package.json
└── nano-jsx
│ ├── nitro.config.ts
│ ├── routes
│ └── [...path].tsx
│ └── package.json
├── .prettierignore
├── lib
├── config.mjs
├── meta.d.mts
├── runtime-meta.d.mts
├── config.d.mts
├── meta.mjs
└── runtime-meta.mjs
├── .editorconfig
├── vitest.config.ts
├── eslint.config.mjs
├── SECURITY.md
├── automd.config.ts
├── .devcontainer
└── devcontainer.json
├── scripts
└── release-nightly.sh
├── LICENSE
├── README.md
├── .gitignore
└── tsconfig.json
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @pi0
--------------------------------------------------------------------------------
/test/fixture/public/foo.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/runtime/internal/empty.ts:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixture/files/sql.sql:
--------------------------------------------------------------------------------
1 | --
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.txt text eol=lf
2 |
--------------------------------------------------------------------------------
/playground/public/test.txt:
--------------------------------------------------------------------------------
1 | Test works!
2 |
--------------------------------------------------------------------------------
/test/fixture/public/build/test.txt:
--------------------------------------------------------------------------------
1 | Works!
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5"
3 | }
4 |
--------------------------------------------------------------------------------
/src/types/virtual/polyfills.ts:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/test/fixture/.gitignore:
--------------------------------------------------------------------------------
1 | !node_modules
2 | !.env
3 |
--------------------------------------------------------------------------------
/test/fixture/public/foo.js:
--------------------------------------------------------------------------------
1 | const hello = "world";
2 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - "examples/**"
3 |
--------------------------------------------------------------------------------
/test/fixture/files/sqlts.sql.ts:
--------------------------------------------------------------------------------
1 | export default "--\n";
2 |
--------------------------------------------------------------------------------
/docs/2.deploy/10.runtimes/_dir.yml:
--------------------------------------------------------------------------------
1 | icon: codicon:run-all
2 |
--------------------------------------------------------------------------------
/docs/2.deploy/20.providers/_dir.yml:
--------------------------------------------------------------------------------
1 | icon: tdesign:cloud
2 |
--------------------------------------------------------------------------------
/test/fixture/assets/test.json:
--------------------------------------------------------------------------------
1 | {
2 | "foo": "bar"
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixture/files/index.html:
--------------------------------------------------------------------------------
1 |
nitro is amazing!
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | ignore-workspace-root-check=true
2 | shell-emulator=true
3 |
--------------------------------------------------------------------------------
/test/fixture/.env:
--------------------------------------------------------------------------------
1 | APP_DOMAIN=test.com
2 | NITRO_DYNAMIC=from-env
3 |
--------------------------------------------------------------------------------
/test/fixture/public/_ignored.txt:
--------------------------------------------------------------------------------
1 | This file should be ignored!
2 |
--------------------------------------------------------------------------------
/test/fixture/utils/test.ts:
--------------------------------------------------------------------------------
1 | export const testUtil = () => 123;
2 |
--------------------------------------------------------------------------------
/src/presets/index.mjs:
--------------------------------------------------------------------------------
1 | export { resolvePreset } from "./_resolve";
2 |
--------------------------------------------------------------------------------
/test/fixture/public/_unignored.txt:
--------------------------------------------------------------------------------
1 | This file should not be ignored!
2 |
--------------------------------------------------------------------------------
/test/fixture/utils/foo/test.ts:
--------------------------------------------------------------------------------
1 | export const testFooUtil = () => 1234;
2 |
--------------------------------------------------------------------------------
/test/fixture/wrangler.toml:
--------------------------------------------------------------------------------
1 | compatibility_flags = [ "nodejs_compat" ]
2 |
--------------------------------------------------------------------------------
/docs/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unknown/nitro/v3/docs/bun.lockb
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["github>unjs/renovate-config"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixture/files/test.txt:
--------------------------------------------------------------------------------
1 | this is an asset from a text file from nitro
2 |
--------------------------------------------------------------------------------
/docs/.config/automd.config.ts:
--------------------------------------------------------------------------------
1 | export { default } from "../../automd.config";
2 |
--------------------------------------------------------------------------------
/test/fixture/api/hey/index.get.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => "Hey API");
2 |
--------------------------------------------------------------------------------
/test/fixture/api/methods/get.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => "get");
2 |
--------------------------------------------------------------------------------
/test/fixture/app.config.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | "app-config": true,
3 | };
4 |
--------------------------------------------------------------------------------
/test/fixture/utils/foo/bar/test.ts:
--------------------------------------------------------------------------------
1 | export const testBarUtil = () => 12_345;
2 |
--------------------------------------------------------------------------------
/playground/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/void.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {});
2 |
--------------------------------------------------------------------------------
/test/fixture/assets/test.md:
--------------------------------------------------------------------------------
1 | # Hello world
2 |
3 | Use `process.env.NODE_ENV` to ...
4 |
--------------------------------------------------------------------------------
/test/fixture/routes/env/index.dev.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => "dev env");
2 |
--------------------------------------------------------------------------------
/test/fixture/server.config.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | "server-config": true,
3 | };
4 |
--------------------------------------------------------------------------------
/examples/api-routes/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/database/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/plugins/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/renderer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/websocket/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixture/api/hello.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({ message: "Hello API" }));
2 |
--------------------------------------------------------------------------------
/test/fixture/api/kebab.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => kebabCase("HelloWorld"));
2 |
--------------------------------------------------------------------------------
/test/fixture/routes/env/index.get.prod.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => "prod env");
2 |
--------------------------------------------------------------------------------
/examples/api-routes/api/hello.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => "Nitro is amazing!");
2 |
--------------------------------------------------------------------------------
/examples/auto-imports/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/cached-handler/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/renderer/api/hello.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => "Nitro is amazing!");
2 |
--------------------------------------------------------------------------------
/examples/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": ["."]
4 | }
5 |
--------------------------------------------------------------------------------
/test/fixture/api/methods/foo.get.get.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => "foo.get");
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-utils/index.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nitro-utils'
2 |
--------------------------------------------------------------------------------
/examples/api-routes/api/test.get.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => "Test get handler");
2 |
--------------------------------------------------------------------------------
/examples/custom-error-handler/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/graceful-shutdown/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.nitro/types/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixture/assets/cat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unknown/nitro/v3/test/fixture/assets/cat.jpg
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-lib/subpath.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nitro-lib@2.0.0';
2 |
--------------------------------------------------------------------------------
/test/fixture/routes/rules/[...slug].ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => event.path);
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | *.md
2 | **/*.gen.ts
3 | node_modules
4 | pnpm-lock.yaml
5 | **/.docs
6 | **/dist/**
7 |
--------------------------------------------------------------------------------
/src/presets/aws-lambda/types.ts:
--------------------------------------------------------------------------------
1 | export interface AwsLambdaOptions {
2 | streaming?: boolean;
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixture/api/methods/index.get.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler<"Index get">(() => "Index get");
2 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/null.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return null;
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-a/index.mjs:
--------------------------------------------------------------------------------
1 | export { default } from '@fixture/nitro-lib'
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/index.mjs:
--------------------------------------------------------------------------------
1 | export { default } from '@fixture/nitro-lib'
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-utils/extra.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nitro-utils/extra'
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-utils/extra2.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nitro-utils/extra2'
2 |
--------------------------------------------------------------------------------
/.github/codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | status:
3 | project:
4 | default:
5 | threshold: 50%
6 |
--------------------------------------------------------------------------------
/examples/hello-world/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .data
4 | .nitro
5 | .cache
6 | .output
7 | .env
8 |
--------------------------------------------------------------------------------
/playground/server/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | return {};
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/api/methods/index.post.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler<"Index post">(() => "Index post");
2 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/date.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => ({ createdAt: new Date() }));
2 |
--------------------------------------------------------------------------------
/test/fixture/api/upload.post.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | return "uploaded!";
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unknown/nitro/v3/test/fixture/public/favicon.ico
--------------------------------------------------------------------------------
/test/fixture/routes/json-string.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => {
2 | return '{"foo":"bar"}';
3 | });
4 |
--------------------------------------------------------------------------------
/src/types/fetch/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./_match";
2 | export * from "./_serialize";
3 | export * from "./fetch";
4 |
--------------------------------------------------------------------------------
/test/fixture/api/methods/default.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler<"Default route">(() => "Default route");
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/node_modules/@fixture/nitro-lib/subpath.mjs:
--------------------------------------------------------------------------------
1 | export default '2.0.1';
2 |
--------------------------------------------------------------------------------
/examples/api-routes/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | });
4 |
--------------------------------------------------------------------------------
/examples/auto-imports/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | });
4 |
--------------------------------------------------------------------------------
/examples/auto-imports/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => `${makeGreeting("Nitro")}
`);
2 |
--------------------------------------------------------------------------------
/examples/auto-imports/utils/hello.ts:
--------------------------------------------------------------------------------
1 | export function makeGreeting(name: string) {
2 | return `Hello, ${name}!`;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | });
4 |
--------------------------------------------------------------------------------
/examples/nano-jsx/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | });
4 |
--------------------------------------------------------------------------------
/lib/config.mjs:
--------------------------------------------------------------------------------
1 | function defineNitroConfig(config) {
2 | return config;
3 | }
4 |
5 | export { defineNitroConfig };
6 |
--------------------------------------------------------------------------------
/src/types/virtual/app-config.d.ts:
--------------------------------------------------------------------------------
1 | import type { AppConfig } from "nitro";
2 |
3 | export const appConfig: AppConfig;
4 |
--------------------------------------------------------------------------------
/examples/cached-handler/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | });
4 |
--------------------------------------------------------------------------------
/examples/middleware/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => ({
2 | auth: event.context.auth,
3 | }));
4 |
--------------------------------------------------------------------------------
/src/types/virtual/storage.d.ts:
--------------------------------------------------------------------------------
1 | import type { Storage } from "unstorage";
2 |
3 | export declare const storage: Storage;
4 |
--------------------------------------------------------------------------------
/test/fixture/api/methods/default.post.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler<"Default override">(() => "Default override");
2 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/function.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return { foo: () => "foo" };
3 | });
4 |
--------------------------------------------------------------------------------
/examples/plugins/plugins/test.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroPlugin((_nitroApp) => {
2 | console.log("Nitro plugin!");
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/set.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return { foo: new Set(["item"]) };
3 | });
4 |
--------------------------------------------------------------------------------
/docs/.docs/public/images/stormkit-deploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unknown/nitro/v3/docs/.docs/public/images/stormkit-deploy.png
--------------------------------------------------------------------------------
/docs/.docs/public/images/stormkit-new-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unknown/nitro/v3/docs/.docs/public/images/stormkit-new-app.png
--------------------------------------------------------------------------------
/examples/hello-world/tsconfig.json:
--------------------------------------------------------------------------------
1 | // https://nitro.build/guide/typescript
2 | {
3 | "extends": "./.nitro/types/tsconfig.json"
4 | }
5 |
--------------------------------------------------------------------------------
/src/types/virtual/plugins.d.ts:
--------------------------------------------------------------------------------
1 | import type { NitroAppPlugin } from "../plugin";
2 |
3 | export const plugins: NitroAppPlugin[] = [];
4 |
--------------------------------------------------------------------------------
/test/fixture/api/_ignored.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | throw createError("This file should be ignored!");
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-lib/node_modules/@fixture/nested-lib/index.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nested-lib@2.0.0'
2 |
--------------------------------------------------------------------------------
/examples/api-routes/api/hello/[name].ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(
2 | (event) => `Hello ${event.context.params.name}!`
3 | );
4 |
--------------------------------------------------------------------------------
/examples/custom-error-handler/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | throw new Error("Example Error!");
3 | });
4 |
--------------------------------------------------------------------------------
/examples/plugins/routes/index.ts:
--------------------------------------------------------------------------------
1 | import { eventHandler } from "h3";
2 |
3 | export default eventHandler(() => "Hello Nitro!
");
4 |
--------------------------------------------------------------------------------
/src/types/runtime/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./asset";
2 | export * from "./cache";
3 | export * from "./nitro";
4 | export * from "./task";
5 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/tuple.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return ["foo", new Date()] as [string, Date];
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/todos/[...].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/todos/**" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/john/index.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/john" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/wildcard/[...param].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | return event.context.params!.param as string;
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/middleware/_ignored.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | throw createError("This file should be ignored!");
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/routes/(route-group)/route-group.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => {
2 | return "Hi from inside group";
3 | });
4 |
--------------------------------------------------------------------------------
/examples/plugins/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | plugins: ["~/plugins/test"],
4 | });
5 |
--------------------------------------------------------------------------------
/examples/renderer/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | renderer: "~/renderer",
4 | });
5 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/error.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return createError({
3 | statusCode: 400,
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/test/fixture/api/serialized/map.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return { foo: new Map([["key", 2]]) };
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/[userId]/index.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/:userId" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/src/presets/index.ts:
--------------------------------------------------------------------------------
1 | export { resolvePreset } from "./_resolve";
2 |
3 | export type { PresetOptions, PresetName, PresetNameInput } from "./_types.gen";
4 |
--------------------------------------------------------------------------------
/test/fixture/routes/500.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => {
2 | throw createError({ statusCode: 500, statusMessage: "Test Error" });
3 | });
4 |
--------------------------------------------------------------------------------
/examples/hello-world/README.md:
--------------------------------------------------------------------------------
1 | # Nitro starter
2 |
3 | Look at the [nitro quick start](https://nitro.build/guide#quick-start) to learn more how to get started.
4 |
--------------------------------------------------------------------------------
/examples/hello-world/server/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | return "Start by editing server/routes/index.ts.";
3 | });
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/catchall/some/[...test].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/catchall/some/**:test" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/john/[johnExtends].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/john/:johnExtends" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/john/post/[postId].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/john/post/:postId" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/john/post/coffee.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/john/post/coffee" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-a/node_modules/@fixture/nitro-lib/node_modules/@fixture/nested-lib/index.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nested-lib@1.0.0'
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/node_modules/@fixture/nitro-lib/node_modules/@fixture/nested-lib/index.mjs:
--------------------------------------------------------------------------------
1 | export default '@fixture/nested-lib@2.0.1'
2 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-lib/index.mjs:
--------------------------------------------------------------------------------
1 | import nestedLib from '@fixture/nested-lib'
2 |
3 | export default '@fixture/nitro-lib@2.0.0+' + nestedLib
4 |
--------------------------------------------------------------------------------
/src/runtime/internal/meta.ts:
--------------------------------------------------------------------------------
1 | import type { NitroRouteMeta } from "nitro/types";
2 |
3 | export function defineRouteMeta(meta: NitroRouteMeta) {
4 | return meta;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/middleware/middleware/auth.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => {
2 | event.context.auth = { name: "User " + Math.round(Math.random() * 100) };
3 | });
4 |
--------------------------------------------------------------------------------
/examples/websocket/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | experimental: {
4 | websocket: true,
5 | },
6 | });
7 |
--------------------------------------------------------------------------------
/lib/meta.d.mts:
--------------------------------------------------------------------------------
1 | import type { CompatibilityUpdate } from "compatx";
2 |
3 | export const version: string;
4 |
5 | export const compatibilityChanges: CompatibilityUpdate[];
6 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/catchall/[slug]/[...another].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/catchall/:slug/**:another" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/[userId]/[userExtends].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/:userId/:userExtends" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/[userId]/post/[postId].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/:userId/post/:postId" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/user/[userId]/post/firstPost.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/user/:userId/post/firstPost" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/examples/hello-world/nitro.config.ts:
--------------------------------------------------------------------------------
1 | // https://nitro.build/config
2 | export default defineNitroConfig({
3 | compatibilityDate: "2025-03-01",
4 | srcDir: "server",
5 | });
6 |
--------------------------------------------------------------------------------
/examples/graceful-shutdown/nitro.config.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroConfig } from "nitro/config";
2 |
3 | export default defineNitroConfig({
4 | compatibilityDate: "2025-03-01",
5 | });
6 |
--------------------------------------------------------------------------------
/test/fixture/routes/error-stack.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | return {
3 | stack: new Error("testing error").stack.replace(/\\/g, "/"),
4 | };
5 | });
6 |
--------------------------------------------------------------------------------
/playground/nitro.config.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroConfig } from "nitro/config";
2 |
3 | export default defineNitroConfig({
4 | compatibilityDate: "latest",
5 | srcDir: "server",
6 | });
7 |
--------------------------------------------------------------------------------
/test/fixture/routes/imports.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return {
3 | testUtil: testUtil(),
4 | testNestedUtil: testFooUtil() + testBarUtil(),
5 | };
6 | });
7 |
--------------------------------------------------------------------------------
/examples/database/nitro.config.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroConfig({
2 | compatibilityDate: "2025-03-01",
3 | experimental: {
4 | database: true,
5 | tasks: true,
6 | },
7 | });
8 |
--------------------------------------------------------------------------------
/test/fixture/api/typed/todos/[todoId]/comments/[...commentId].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => ({
2 | internalApiKey: "/api/typed/todos/:todoId/comments/**:commentId" as const,
3 | }));
4 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-lib/node_modules/@fixture/nested-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nested-lib",
3 | "version": "2.0.0",
4 | "exports": "./index.mjs"
5 | }
6 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-a/node_modules/@fixture/nitro-lib/index.mjs:
--------------------------------------------------------------------------------
1 | import nestedLib from '@fixture/nested-lib'
2 |
3 | export default '@fixture/nitro-lib@1.0.0+' + nestedLib
4 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/node_modules/@fixture/nitro-lib/index.mjs:
--------------------------------------------------------------------------------
1 | import nestedLib from '@fixture/nested-lib'
2 |
3 | export default '@fixture/nitro-lib@2.0.1+' + nestedLib
4 |
--------------------------------------------------------------------------------
/test/fixture/api/param/[test-id].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | setHeader(event, "Content-Type", "text/plain; charset=utf-16");
3 | return event.context.params!["test-id"];
4 | });
5 |
--------------------------------------------------------------------------------
/lib/runtime-meta.d.mts:
--------------------------------------------------------------------------------
1 | export declare const pkgDir: string;
2 | export declare const runtimeDir: string;
3 | export declare const subpaths: string[];
4 | export declare const runtimeDependencies: string[];
5 |
--------------------------------------------------------------------------------
/src/types/virtual/server-assets.d.ts:
--------------------------------------------------------------------------------
1 | export function readAsset(id: string): Promise;
2 | export function statAsset(id: string): Promise;
3 | export function getKeys(): Promise;
4 |
--------------------------------------------------------------------------------
/test/fixture/api/storage/dev.dev.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(async (event) => {
2 | const storage = useStorage();
3 | return {
4 | keys: await storage.getKeys("/src/public"),
5 | };
6 | });
7 |
--------------------------------------------------------------------------------
/test/fixture/routes/assets/md.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const md = await import("../../assets/test.md" as string).then(
3 | (r) => r.default
4 | );
5 | return md;
6 | });
7 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "undocs dev",
5 | "build": "undocs build"
6 | },
7 | "devDependencies": {
8 | "undocs": "^0.2.30"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/presets/_nitro/preset.ts:
--------------------------------------------------------------------------------
1 | import worker from "./base-worker";
2 | import dev from "./nitro-dev";
3 | import prerender from "./nitro-prerender";
4 |
5 | export default [...worker, ...dev, ...prerender] as const;
6 |
--------------------------------------------------------------------------------
/test/fixture/api/echo.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler((event) => {
2 | return {
3 | url: event.path,
4 | method: event.method,
5 | headers: Object.fromEntries(event.headers.entries()),
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/test/fixture/api/error.ts:
--------------------------------------------------------------------------------
1 | import { createError } from "h3";
2 | export default eventHandler(() => {
3 | throw createError({
4 | statusCode: 503,
5 | statusMessage: "Service Unavailable",
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/test/fixture/public/cf-pages-exclude/not-in-routes-json.txt:
--------------------------------------------------------------------------------
1 | This file shouldn't be under "exclude" in the _routes.json outputted by Cloudflare Pages builds.
2 | It's covered by the "/cf-pages-exclude/*" wildcard.
3 |
--------------------------------------------------------------------------------
/examples/api-routes/api/test.post.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(async (event) => {
2 | const body = await readBody(event);
3 | return {
4 | message: "Test post handler",
5 | body,
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/lib/config.d.mts:
--------------------------------------------------------------------------------
1 | import { NitroConfig } from "nitro/types";
2 |
3 | export { NitroConfig } from "nitro/types";
4 |
5 | declare function defineNitroConfig(config: NitroConfig): NitroConfig;
6 |
7 | export { defineNitroConfig };
8 |
--------------------------------------------------------------------------------
/src/runtime/internal/plugin.ts:
--------------------------------------------------------------------------------
1 | import type { NitroAppPlugin } from "nitro/types";
2 |
3 | export function defineNitroPlugin(def: NitroAppPlugin) {
4 | return def;
5 | }
6 |
7 | export const nitroPlugin = defineNitroPlugin;
8 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-a/node_modules/@fixture/nitro-lib/node_modules/@fixture/nested-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nested-lib",
3 | "version": "1.0.0",
4 | "exports": "./index.mjs"
5 | }
6 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/node_modules/@fixture/nitro-lib/node_modules/@fixture/nested-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nested-lib",
3 | "version": "2.0.1",
4 | "exports": "./index.mjs"
5 | }
6 |
--------------------------------------------------------------------------------
/src/types/virtual/database.d.ts:
--------------------------------------------------------------------------------
1 | import type { Connector } from "db0";
2 |
3 | export declare const connectionConfigs: {
4 | [name: string]: {
5 | connector: (options: any) => Connector;
6 | options: any;
7 | };
8 | };
9 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-a/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nitro-dep-a",
3 | "version": "1.0.0",
4 | "exports": "./index.mjs",
5 | "dependencies": {
6 | "@fixture/nitro-lib": "1.0.0"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nitro-dep-b",
3 | "version": "2.0.1",
4 | "exports": "./index.mjs",
5 | "dependencies": {
6 | "@fixture/nitro-lib": "2.0.1"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/custom-error-handler/nitro.config.ts:
--------------------------------------------------------------------------------
1 | import errorHandler from "./error";
2 |
3 | export default defineNitroConfig({
4 | compatibilityDate: "2025-03-01",
5 | errorHandler: "~/error",
6 | devErrorHandler: errorHandler,
7 | });
8 |
--------------------------------------------------------------------------------
/src/runtime/internal/debug.ts:
--------------------------------------------------------------------------------
1 | import { createDebugger } from "hookable";
2 | import { defineNitroPlugin } from "./plugin";
3 |
4 | export default defineNitroPlugin((nitro) => {
5 | createDebugger(nitro.hooks, { tag: "nitro-runtime" });
6 | });
7 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-a/node_modules/@fixture/nitro-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nitro-lib",
3 | "version": "1.0.0",
4 | "exports": "./index.mjs",
5 | "dependencies": {
6 | "nested-lib": "1.0.0"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/database/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-database",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/plugins/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-plugins",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-renderer",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/fixture/api/cached.ts:
--------------------------------------------------------------------------------
1 | export default defineCachedEventHandler(
2 | (event) => {
3 | return {
4 | timestamp: Date.now(),
5 | eventContextCache: event.context.cache,
6 | };
7 | },
8 | { swr: true, maxAge: 60 }
9 | );
10 |
--------------------------------------------------------------------------------
/examples/api-routes/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-api-routes",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/middleware/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-middleware",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/websocket/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-websocket",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/fixture/plugins/errors.ts:
--------------------------------------------------------------------------------
1 | export const allErrors: { error: Error; context: any }[] = [];
2 |
3 | export default defineNitroPlugin((app) => {
4 | app.hooks.hook("error", (error, context) => {
5 | allErrors.push({ error, context });
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/test/fixture/tasks/db/migrate.ts:
--------------------------------------------------------------------------------
1 | export default defineTask({
2 | meta: {
3 | description: "Run database migrations",
4 | },
5 | run() {
6 | console.log("Running DB migration task...");
7 | return { result: "Success" };
8 | },
9 | });
10 |
--------------------------------------------------------------------------------
/examples/auto-imports/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-auto-imports",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/custom-error-handler/error.ts:
--------------------------------------------------------------------------------
1 | import type { NitroErrorHandler } from "nitro";
2 |
3 | const errorHandler: NitroErrorHandler = function (error, event) {
4 | event.res.end("[custom error handler] " + error.stack);
5 | };
6 |
7 | export default errorHandler;
8 |
--------------------------------------------------------------------------------
/src/runtime/internal/client.ts:
--------------------------------------------------------------------------------
1 | import type { $Fetch, NitroFetchRequest } from "nitro/types";
2 | // Client polyfill
3 | import { $fetch } from "ofetch";
4 |
5 | if (!globalThis.$fetch) {
6 | globalThis.$fetch = $fetch as $Fetch;
7 | }
8 |
--------------------------------------------------------------------------------
/src/types/virtual/server-handlers-meta.d.ts:
--------------------------------------------------------------------------------
1 | import type { OperationObject } from "../openapi-ts";
2 | import { NitroRouteMeta } from "nitro/types";
3 |
4 | export const handlersMeta: {
5 | route?: string;
6 | method?: string;
7 | meta?: NitroRouteMeta;
8 | }[];
9 |
--------------------------------------------------------------------------------
/test/fixture/api/errors.ts:
--------------------------------------------------------------------------------
1 | import { allErrors } from "../plugins/errors";
2 |
3 | export default eventHandler((event) => {
4 | return {
5 | allErrors: allErrors.map((entry) => ({
6 | message: entry.error.message,
7 | })),
8 | };
9 | });
10 |
--------------------------------------------------------------------------------
/examples/cached-handler/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-cached-handler",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/nano-jsx/routes/[...path].tsx:
--------------------------------------------------------------------------------
1 | import { defineEventHandler } from "h3";
2 | import { h, renderSSR } from "nano-jsx";
3 |
4 | export default defineEventHandler(() => {
5 | const html = renderSSR(() => Nitro + nano-jsx works!
);
6 | return html;
7 | });
8 |
--------------------------------------------------------------------------------
/src/types/module.ts:
--------------------------------------------------------------------------------
1 | import type { Nitro } from "./nitro";
2 |
3 | export type NitroModuleInput = string | NitroModule | NitroModule["setup"];
4 |
5 | export interface NitroModule {
6 | name?: string;
7 | setup: (this: void, nitro: Nitro) => void | Promise;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/graceful-shutdown/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-graceful-shutdown",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/custom-error-handler/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-custom-error-handler",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/hello-world/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "scripts": {
4 | "build": "nitro build",
5 | "dev": "nitro dev",
6 | "preview": "node .output/server/index.mjs"
7 | },
8 | "devDependencies": {
9 | "nitropack": "latest"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/types/virtual/tasks.ts:
--------------------------------------------------------------------------------
1 | import type { Task, TaskMeta } from "nitro/types";
2 |
3 | export const tasks: Record<
4 | string,
5 | { resolve?: () => Promise; meta: TaskMeta }
6 | > = {};
7 |
8 | export const scheduledTasks: false | { cron: string; tasks: string[] }[] = [];
9 |
--------------------------------------------------------------------------------
/test/fixture/routes/config.ts:
--------------------------------------------------------------------------------
1 | const sharedRuntimeConfig = useRuntimeConfig();
2 |
3 | export default eventHandler((event) => {
4 | const runtimeConfig = useRuntimeConfig(event);
5 |
6 | return {
7 | runtimeConfig,
8 | sharedRuntimeConfig,
9 | };
10 | });
11 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nitro-utils",
3 | "private": true,
4 | "type": "module",
5 | "exports": {
6 | ".": "./index.mjs",
7 | "./extra": "./extra.mjs",
8 | "./extra2": "./extra2.mjs"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/nano-jsx/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-nano-jsx",
3 | "private": true,
4 | "scripts": {
5 | "dev": "nitro dev",
6 | "build": "nitro build"
7 | },
8 | "devDependencies": {
9 | "nano-jsx": "^0.0.37",
10 | "nitropack": "latest"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/test/fixture/routes/wasm/static-import.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | import init, { sum } from "unwasm/examples/sum.wasm";
3 |
4 | export default defineLazyEventHandler(async () => {
5 | await init();
6 | return eventHandler(() => {
7 | return `2+3=${sum(2, 3)}`;
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/src/config/resolvers/url.ts:
--------------------------------------------------------------------------------
1 | import type { NitroOptions } from "nitro/types";
2 | import { withLeadingSlash, withTrailingSlash } from "ufo";
3 |
4 | export async function resolveURLOptions(options: NitroOptions) {
5 | options.baseURL = withLeadingSlash(withTrailingSlash(options.baseURL));
6 | }
7 |
--------------------------------------------------------------------------------
/examples/graceful-shutdown/routes/index.ts:
--------------------------------------------------------------------------------
1 | import { eventHandler } from "h3";
2 |
3 | export default eventHandler(async () => {
4 | console.log("Event handler is running...");
5 | await new Promise((resolve) => setTimeout(resolve, 2000));
6 | return { message: "Response took 2 seconds" };
7 | });
8 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 | charset = utf-8
8 |
9 | [*.js]
10 | indent_style = space
11 | indent_size = 2
12 |
13 | [{package.json,*.yml,*.cjson}]
14 | indent_style = space
15 | indent_size = 2
16 |
--------------------------------------------------------------------------------
/test/fixture/routes/context.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(async () => {
2 | await Promise.resolve(setTimeout(() => {}, 10));
3 | return await useTest();
4 | });
5 |
6 | function useTest() {
7 | return {
8 | context: {
9 | path: useEvent().path,
10 | },
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/src/presets/genezio/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const genezio = defineNitroPreset(
4 | {
5 | extends: "aws_lambda",
6 | },
7 | {
8 | name: "genezio" as const,
9 | url: import.meta.url,
10 | }
11 | );
12 | export default [genezio] as const;
13 |
--------------------------------------------------------------------------------
/src/types/virtual/error-handler.d.ts:
--------------------------------------------------------------------------------
1 | import type { NitroErrorHandler } from "nitro/types";
2 |
3 | type EParams = Parameters;
4 | type EReturn = ReturnType;
5 |
6 | const errorHandler: (error: EParams[0], event: EParams[1]) => EReturn;
7 |
8 | export default errorHandler;
9 |
--------------------------------------------------------------------------------
/examples/api-routes/routes/[...].ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(() => {
2 | return `
3 | API Routes:
4 |
9 | `;
10 | });
11 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-dep-b/node_modules/@fixture/nitro-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nitro-lib",
3 | "version": "2.0.1",
4 | "exports": {
5 | ".": "./index.mjs",
6 | "./subpath": "./subpath.mjs"
7 | },
8 | "dependencies": {
9 | "nested-lib": "2.0.1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/test/fixture/routes/wasm/dynamic-import.ts:
--------------------------------------------------------------------------------
1 | export default defineLazyEventHandler(async () => {
2 | // @ts-ignore
3 | const { sum } = await import("unwasm/examples/sum.wasm").then((r) =>
4 | r.default()
5 | );
6 | return eventHandler(() => {
7 | return `2+3=${sum(2, 3)}`;
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/src/utils/nitro.ts:
--------------------------------------------------------------------------------
1 | import type { Nitro } from "nitro/types";
2 | import { upperFirst } from "scule";
3 |
4 | export function nitroServerName(nitro: Nitro) {
5 | return nitro.options.framework.name === "nitro"
6 | ? "Nitro Server"
7 | : `${upperFirst(nitro.options.framework.name as string)} Nitro server`;
8 | }
9 |
--------------------------------------------------------------------------------
/src/types/virtual/public-assets.d.ts:
--------------------------------------------------------------------------------
1 | export const publicAssetBases: string[];
2 | export const isPublicAssetURL: (id: string) => boolean;
3 | export const getPublicAssetMeta: (id: string) => { maxAge?: number };
4 | export const readAsset: (id: string) => Promise;
5 | export const getAsset: (id: string) => PublicAsset;
6 |
--------------------------------------------------------------------------------
/test/fixture/api/storage/item.put.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const { base = "", key = "" } = getQuery(event) as Record;
3 | const storage = useStorage(`test:${base}`);
4 | const value = await readBody(event);
5 | await storage.setItem(key, value);
6 | return value;
7 | });
8 |
--------------------------------------------------------------------------------
/test/fixture/node_modules/@fixture/nitro-lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@fixture/nitro-lib-aliased-from-another-name",
3 | "version": "2.0.0",
4 | "exports": {
5 | ".": "./index.mjs",
6 | "./subpath": "./subpath.mjs"
7 | },
8 | "dependencies": {
9 | "@fixture/nested-lib": "2.0.0"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/types/runtime/asset.ts:
--------------------------------------------------------------------------------
1 | export interface PublicAsset {
2 | type: string;
3 | etag: string;
4 | mtime: string;
5 | path: string;
6 | size: number;
7 | encoding?: string;
8 | data?: string;
9 | }
10 |
11 | export interface AssetMeta {
12 | type?: string;
13 | etag?: string;
14 | mtime?: string;
15 | }
16 |
--------------------------------------------------------------------------------
/test/fixture/routes/tasks/[...name].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const name = getRouterParam(event, "name");
3 | const payload = { ...getQuery(event) };
4 | const { result } = await runTask(name, { payload });
5 | return {
6 | name,
7 | payload,
8 | result,
9 | };
10 | });
11 |
--------------------------------------------------------------------------------
/src/presets/azure/types.ts:
--------------------------------------------------------------------------------
1 | export interface AzureOptions {
2 | config?: {
3 | platform?: {
4 | apiRuntime?: string;
5 | [key: string]: unknown;
6 | };
7 | navigationFallback?: {
8 | rewrite?: string;
9 | [key: string]: unknown;
10 | };
11 | [key: string]: unknown;
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/test/fixture/routes/raw.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | import sql from "../files/sql.sql";
3 |
4 | // https://github.com/nitrojs/nitro/issues/2836
5 | import sqlts from "../files/sqlts.sql";
6 |
7 | export default defineEventHandler(async () => {
8 | return {
9 | sql: sql.trim(),
10 | sqlts: sqlts.trim(),
11 | };
12 | });
13 |
--------------------------------------------------------------------------------
/src/presets/koyeb/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const koyeb = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "koyeb" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | export default [koyeb] as const;
15 |
--------------------------------------------------------------------------------
/src/presets/netlify/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Netlify options
3 | */
4 | export interface NetlifyOptions {
5 | images?: {
6 | /**
7 | * Permitted remote image sources. Array of regex strings.
8 | * @see https://docs.netlify.com/image-cdn/overview/#remote-path
9 | */
10 | remote_images?: string[];
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/test/fixture/routes/file.ts:
--------------------------------------------------------------------------------
1 | import { useStorage } from "nitro/runtime";
2 |
3 | export default defineEventHandler(async (event) => {
4 | const query = getQuery(event);
5 | const filename = query?.filename || "index.html";
6 | const serverAsset = await useStorage().getItem(`assets/files/${filename}`);
7 | return serverAsset;
8 | });
9 |
--------------------------------------------------------------------------------
/src/presets/heroku/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const heroku = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "heroku" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | export default [heroku] as const;
15 |
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vitest/config";
2 |
3 | export default defineConfig({
4 | test: {
5 | testTimeout: 30_000,
6 | coverage: {
7 | reporter: ["text", "clover", "json"],
8 | include: ["src/**/*.ts", "!src/types/**/*.ts"],
9 | },
10 | include: ["test/**/*.test.ts"],
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/src/cli/common.ts:
--------------------------------------------------------------------------------
1 | import type { ArgsDef } from "citty";
2 |
3 | export const commonArgs = {
4 | dir: {
5 | type: "string",
6 | description: "project root directory",
7 | },
8 | _dir: {
9 | type: "positional",
10 | default: ".",
11 | description: "project root directory (prefer using `--dir`)",
12 | },
13 | };
14 |
--------------------------------------------------------------------------------
/src/presets/render.com/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const renderCom = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "render-com" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | export default [renderCom] as const;
15 |
--------------------------------------------------------------------------------
/test/fixture/routes/jsx.tsx:
--------------------------------------------------------------------------------
1 | const h = (tag: string, props: any, ...children: any[]) => {
2 | return `<${tag} ${Object.keys(props || {})
3 | .map((key) => `${key}="${props[key]}"`)
4 | .join(" ")
5 | .trim()}>${children.join("")}${tag}>`;
6 | };
7 |
8 | export default eventHandler(() => {
9 | return Hello JSX!
;
10 | });
11 |
--------------------------------------------------------------------------------
/examples/cached-handler/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default defineCachedEventHandler(
2 | async () => {
3 | await new Promise((resolve) => setTimeout(resolve, 1000));
4 | return `Response generated at ${new Date().toISOString()} (took 1 second)`;
5 | },
6 | {
7 | shouldBypassCache: (e) => e.node.req.url.includes("preview"),
8 | }
9 | );
10 |
--------------------------------------------------------------------------------
/src/presets/platform.sh/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const platformSh = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "platform-sh" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | export default [platformSh] as const;
15 |
--------------------------------------------------------------------------------
/test/fixture/api/headers.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => {
2 | setHeader(event, "x-foo", "bar");
3 | setHeader(event, "x-array", ["foo", "bar"]);
4 |
5 | setHeader(event, "Set-Cookie", "foo=bar, bar=baz");
6 | setCookie(event, "test", "value");
7 | setCookie(event, "test2", "value");
8 |
9 | return "headers sent";
10 | });
11 |
--------------------------------------------------------------------------------
/test/fixture/plugins/vary.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroPlugin((app) => {
2 | app.hooks.hook("request", (event) => {
3 | if (event.path.endsWith(".css")) {
4 | setResponseHeader(event, "Vary", "Origin");
5 | }
6 | if (event.path.endsWith(".js")) {
7 | setResponseHeader(event, "Vary", ["Origin"]);
8 | }
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/src/presets/cleavr/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const cleavr = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "cleavr" as const,
10 | stdName: "cleavr",
11 | url: import.meta.url,
12 | }
13 | );
14 |
15 | export default [cleavr] as const;
16 |
--------------------------------------------------------------------------------
/src/presets/digitalocean/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const digitalOcean = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "digital-ocean" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | export default [digitalOcean] as const;
15 |
--------------------------------------------------------------------------------
/src/presets/flightcontrol/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const flightControl = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "flight-control" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | export default [flightControl] as const;
15 |
--------------------------------------------------------------------------------
/src/cli/commands/task/index.ts:
--------------------------------------------------------------------------------
1 | import { defineCommand } from "citty";
2 |
3 | export default defineCommand({
4 | meta: {
5 | name: "task",
6 | description: "Operate in nitro tasks (experimental)",
7 | },
8 | subCommands: {
9 | list: () => import("./list").then((r) => r.default),
10 | run: () => import("./run").then((r) => r.default),
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/src/presets/zeabur/runtime/zeabur.ts:
--------------------------------------------------------------------------------
1 | import "#nitro-internal-pollyfills";
2 | import { type NodeListener, toNodeListener } from "h3";
3 | import { useNitroApp } from "nitro/runtime";
4 |
5 | const handler = toNodeListener(useNitroApp().h3App);
6 |
7 | const listener: NodeListener = function (req, res) {
8 | return handler(req, res);
9 | };
10 |
11 | export default listener;
12 |
--------------------------------------------------------------------------------
/test/fixture/api/storage/item.get.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const { base = "", key = "" } = getQuery(event) as Record;
3 | const storage = useStorage(`test:${base}`);
4 |
5 | if (!key || key.endsWith(":")) {
6 | return await storage.getKeys();
7 | }
8 |
9 | const value = await storage.getItem(key);
10 | return value;
11 | });
12 |
--------------------------------------------------------------------------------
/src/types/virtual/server-handlers.d.ts:
--------------------------------------------------------------------------------
1 | import type { H3EventHandler, LazyEventHandler, RouterMethod } from "h3";
2 |
3 | type HandlerDefinition = {
4 | route: string;
5 | lazy?: boolean;
6 | middleware?: boolean;
7 | handler: H3EventHandler;
8 | method?: RouterMethod;
9 | } & {
10 | lazy: true;
11 | handler: LazyEventHandler;
12 | };
13 |
14 | export const handlers: HandlerDefinition[];
15 |
--------------------------------------------------------------------------------
/examples/renderer/renderer.ts:
--------------------------------------------------------------------------------
1 | import { defineRenderHandler } from "nitro/runtime";
2 |
3 | export default defineRenderHandler((_event) => {
4 | return {
5 | body: /* html */ `
6 |
7 |
8 | Rendered Page
9 |
10 |
11 | Rendered by Nitro!
12 |
13 | `,
14 | };
15 | });
16 |
--------------------------------------------------------------------------------
/test/fixture/routes/wait-until.ts:
--------------------------------------------------------------------------------
1 | const timeTakingOperation = async () => {
2 | // console.log("wait-until.ts: timeTakingOperation() start");
3 | await new Promise((resolve) => setTimeout(resolve, 100));
4 | // console.log("wait-until.ts: timeTakingOperation() done");
5 | };
6 |
7 | export default eventHandler((event) => {
8 | event.waitUntil(timeTakingOperation());
9 |
10 | return "done";
11 | });
12 |
--------------------------------------------------------------------------------
/src/runtime/internal/error/utils.ts:
--------------------------------------------------------------------------------
1 | import type { NitroErrorHandler } from "nitro/types";
2 |
3 | export function defineNitroErrorHandler(
4 | handler: NitroErrorHandler
5 | ): NitroErrorHandler {
6 | return handler;
7 | }
8 |
9 | export type InternalHandlerResponse = {
10 | status: number;
11 | statusText: string;
12 | headers: Record;
13 | body: string | Record;
14 | };
15 |
--------------------------------------------------------------------------------
/src/runtime/internal/storage.ts:
--------------------------------------------------------------------------------
1 | import type { Storage, StorageValue } from "unstorage";
2 | import { prefixStorage } from "unstorage";
3 | import { storage } from "#nitro-internal-virtual/storage";
4 |
5 | export function useStorage(
6 | base = ""
7 | ): Storage {
8 | return (base
9 | ? prefixStorage(storage, base)
10 | : storage) as unknown as Storage;
11 | }
12 |
--------------------------------------------------------------------------------
/test/fixture/routes/stream.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(() => {
2 | const encoder = new TextEncoder();
3 | const stream = new ReadableStream({
4 | start(controller) {
5 | controller.enqueue(encoder.encode("nitro"));
6 | controller.enqueue(encoder.encode("is"));
7 | controller.enqueue(encoder.encode("awesome"));
8 | controller.close();
9 | },
10 | });
11 | return stream;
12 | });
13 |
--------------------------------------------------------------------------------
/test/fixture/error.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroErrorHandler } from "nitro/runtime";
2 | import { send } from "h3";
3 | export default defineNitroErrorHandler(
4 | async (error, event, { defaultHandler }) => {
5 | if (event.path.includes("?json")) {
6 | const response = await defaultHandler(error, event, { json: true });
7 | return send(event, JSON.stringify({ json: response.body }, null, 2));
8 | }
9 | }
10 | );
11 |
--------------------------------------------------------------------------------
/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./fetch";
2 | export * from "./runtime";
3 | export * from "./config";
4 | export * from "./dev";
5 | export * from "./global";
6 | export * from "./h3";
7 | export * from "./handler";
8 | export * from "./hooks";
9 | export * from "./module";
10 | export * from "./nitro";
11 | export * from "./prerender";
12 | export * from "./preset";
13 | export * from "./rollup";
14 | export * from "./route-rules";
15 |
--------------------------------------------------------------------------------
/examples/graceful-shutdown/plugins/db.ts:
--------------------------------------------------------------------------------
1 | export default defineNitroPlugin((nitroApp) => {
2 | nitroApp.hooks.hookOnce("close", async () => {
3 | console.log("Disconnecting database...");
4 |
5 | // something you want to do, such like disconnect the database, or wait until the task is done
6 | await new Promise((resolve) => setTimeout(resolve, 500));
7 |
8 | console.log("Database is disconnected!");
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/src/presets/_nitro/runtime/nitro-prerenderer.ts:
--------------------------------------------------------------------------------
1 | import "#nitro-internal-pollyfills";
2 | import { useNitroApp } from "nitro/runtime";
3 | import { trapUnhandledNodeErrors } from "nitro/runtime/internal";
4 |
5 | const nitroApp = useNitroApp();
6 |
7 | export const localFetch = nitroApp.localFetch;
8 | export const closePrerenderer = () => nitroApp.hooks.callHook("close");
9 |
10 | // Trap unhandled errors
11 | trapUnhandledNodeErrors();
12 |
--------------------------------------------------------------------------------
/src/types/preset.ts:
--------------------------------------------------------------------------------
1 | import type { DateString } from "compatx";
2 | import type { ProviderName } from "std-env";
3 | import type { NitroConfig } from "./config";
4 |
5 | export type NitroPreset = NitroConfig | (() => NitroConfig);
6 |
7 | export interface NitroPresetMeta {
8 | url: string;
9 | name: string;
10 | stdName?: ProviderName;
11 | aliases?: string[];
12 | static?: boolean;
13 | compatibilityDate?: DateString;
14 | }
15 |
--------------------------------------------------------------------------------
/src/types/prerender.ts:
--------------------------------------------------------------------------------
1 | export interface PrerenderRoute {
2 | route: string;
3 | contents?: string;
4 | data?: ArrayBuffer;
5 | fileName?: string;
6 | error?: Error & { statusCode: number; statusMessage: string };
7 | generateTimeMS?: number;
8 | skip?: boolean;
9 | contentType?: string;
10 | }
11 |
12 | /** @deprecated Internal type will be removed in future versions */
13 | export type PrerenderGenerateRoute = PrerenderRoute;
14 |
--------------------------------------------------------------------------------
/src/build/plugins/server-main.ts:
--------------------------------------------------------------------------------
1 | import type { Nitro } from "nitro/types";
2 | import type { Plugin } from "rollup";
3 |
4 | export function serverMain(nitro: Nitro): Plugin {
5 | return {
6 | name: "nitro:server-main",
7 | renderChunk(code, chunk) {
8 | if (chunk.isEntry) {
9 | return {
10 | code: `globalThis.__nitro_main__ = import.meta.url; ${code}`,
11 | map: null,
12 | };
13 | }
14 | },
15 | };
16 | }
17 |
--------------------------------------------------------------------------------
/src/presets/stormkit/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const stormkit = defineNitroPreset(
4 | {
5 | entry: "./runtime/stormkit",
6 | output: {
7 | dir: "{{ rootDir }}/.stormkit",
8 | publicDir: "{{ rootDir }}/.stormkit/public/{{ baseURL }}",
9 | },
10 | },
11 | {
12 | name: "stormkit" as const,
13 | stdName: "stormkit",
14 | url: import.meta.url,
15 | }
16 | );
17 |
18 | export default [stormkit] as const;
19 |
--------------------------------------------------------------------------------
/src/presets/_nitro/nitro-prerender.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const nitroPrerender = defineNitroPreset(
4 | {
5 | entry: "./runtime/nitro-prerenderer",
6 | serveStatic: true,
7 | output: {
8 | serverDir: "{{ buildDir }}/prerender",
9 | },
10 | externals: { trace: false },
11 | },
12 | {
13 | name: "nitro-prerender" as const,
14 | url: import.meta.url,
15 | }
16 | );
17 |
18 | export default [nitroPrerender] as const;
19 |
--------------------------------------------------------------------------------
/src/presets/alwaysdata/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const alwaysdata = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | commands: {
8 | deploy:
9 | "rsync -rRt --info=progress2 ./ [account]@ssh-[account].alwaysdata.net:www/my-app",
10 | },
11 | },
12 | {
13 | name: "alwaysdata" as const,
14 | url: import.meta.url,
15 | }
16 | );
17 |
18 | export default [alwaysdata] as const;
19 |
--------------------------------------------------------------------------------
/test/fixture/tasks/test.ts:
--------------------------------------------------------------------------------
1 | export default defineTask({
2 | meta: {
3 | description: "task to debug",
4 | },
5 | async run(taskEvent) {
6 | console.log("test task", taskEvent);
7 | if (taskEvent.payload.wait) {
8 | await new Promise((resolve) =>
9 | setTimeout(resolve, Number(taskEvent.payload.wait))
10 | );
11 | }
12 | if (taskEvent.payload.error) {
13 | throw new Error("test error");
14 | }
15 | return { result: taskEvent };
16 | },
17 | });
18 |
--------------------------------------------------------------------------------
/src/presets/_nitro/nitro-dev.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const nitroDev = defineNitroPreset(
4 | {
5 | entry: "./runtime/nitro-dev",
6 | output: {
7 | serverDir: "{{ buildDir }}/dev",
8 | },
9 | externals: { trace: false },
10 | inlineDynamicImports: true, // externals plugin limitation
11 | sourceMap: true,
12 | },
13 | {
14 | name: "nitro-dev" as const,
15 | url: import.meta.url,
16 | }
17 | );
18 |
19 | export default [nitroDev] as const;
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: 📚 Nitro Documentation
4 | url: https://nitro.build/
5 | about: Check the documentation for usage of Nuxt 3
6 | - name: 💬 Discussions
7 | url: https://github.com/nitrojs/nitro/discussions
8 | about: Use discussions if you have an idea for improvement and asking questions
9 | - name: 🔗 Nuxt related Issues
10 | url: https://github.com/nuxt/nuxt/issues/new/choose
11 | about: Please open an issue in nuxt/nuxt to discuss
12 |
--------------------------------------------------------------------------------
/src/build/rollup/build.ts:
--------------------------------------------------------------------------------
1 | import { getRollupConfig } from "./config";
2 | import type { Nitro } from "nitro/types";
3 | import { watchDev } from "./dev";
4 | import { buildProduction } from "./prod";
5 |
6 | export async function rollupBuild(nitro: Nitro) {
7 | await nitro.hooks.callHook("build:before", nitro);
8 | const config = getRollupConfig(nitro);
9 | await nitro.hooks.callHook("rollup:before", nitro, config);
10 | return nitro.options.dev
11 | ? watchDev(nitro, config)
12 | : buildProduction(nitro, config);
13 | }
14 |
--------------------------------------------------------------------------------
/src/presets/bun/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const bun = defineNitroPreset(
4 | {
5 | entry: "./runtime/bun",
6 | serveStatic: true,
7 | // https://bun.sh/docs/runtime/modules#resolution
8 | exportConditions: ["bun", "worker", "node", "import", "default"],
9 | commands: {
10 | preview: "bun run ./server/index.mjs",
11 | },
12 | },
13 | {
14 | name: "bun" as const,
15 | url: import.meta.url,
16 | }
17 | );
18 |
19 | export default [bun] as const;
20 |
--------------------------------------------------------------------------------
/src/presets/cloudflare/wrangler/_utils.ts:
--------------------------------------------------------------------------------
1 | // Extracted from @types/yargs
2 | type PascalCase = string extends S
3 | ? string
4 | : S extends `${infer T}-${infer U}`
5 | ? `${Capitalize}${PascalCase}`
6 | : Capitalize;
7 |
8 | type CamelCase = string extends S
9 | ? string
10 | : S extends `${infer T}-${infer U}`
11 | ? `${T}${PascalCase}`
12 | : S;
13 |
14 | export type CamelCaseKey = K extends string
15 | ? Exclude, "">
16 | : K;
17 |
--------------------------------------------------------------------------------
/src/presets/aws-amplify/runtime/aws-amplify.ts:
--------------------------------------------------------------------------------
1 | import "#nitro-internal-pollyfills";
2 | import { useNitroApp } from "nitro/runtime";
3 |
4 | import { Server } from "node:http";
5 | import { toNodeListener } from "h3";
6 |
7 | const nitroApp = useNitroApp();
8 |
9 | const server = new Server(toNodeListener(nitroApp.h3App));
10 |
11 | // @ts-ignore
12 | server.listen(3000, (err) => {
13 | if (err) {
14 | console.error(err);
15 | } else {
16 | console.log(`Listening on http://localhost:3000 (AWS Amplify Hosting)`);
17 | }
18 | });
19 |
--------------------------------------------------------------------------------
/src/build/build.ts:
--------------------------------------------------------------------------------
1 | import type { Nitro } from "nitro/types";
2 |
3 | export async function build(nitro: Nitro) {
4 | switch (nitro.options.builder) {
5 | case "rollup": {
6 | const { rollupBuild } = await import("./rollup/build");
7 | return rollupBuild(nitro);
8 | }
9 | case "rolldown": {
10 | const { rolldownBuild } = await import("./rolldown/build");
11 | return rolldownBuild(nitro);
12 | }
13 | default: {
14 | throw new Error(`Unknown builder: ${nitro.options.builder}`);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/build/rolldown/build.ts:
--------------------------------------------------------------------------------
1 | import { getRolldownConfig } from "./config";
2 | import type { Nitro } from "nitro/types";
3 | import { watchDev } from "./dev";
4 | import { buildProduction } from "./prod";
5 |
6 | export async function rolldownBuild(nitro: Nitro) {
7 | await nitro.hooks.callHook("build:before", nitro);
8 | const config = getRolldownConfig(nitro);
9 | await nitro.hooks.callHook("rollup:before", nitro, config as any);
10 | return nitro.options.dev
11 | ? watchDev(nitro, config)
12 | : buildProduction(nitro, config);
13 | }
14 |
--------------------------------------------------------------------------------
/examples/database/tasks/db/migrate.ts:
--------------------------------------------------------------------------------
1 | export default defineTask({
2 | meta: {
3 | description: "Run database migrations",
4 | },
5 | async run() {
6 | const db = useDatabase();
7 |
8 | console.log("Running database migrations...");
9 |
10 | // Create users table
11 | await db.sql`DROP TABLE IF EXISTS users`;
12 | await db.sql`CREATE TABLE IF NOT EXISTS users ("id" TEXT PRIMARY KEY, "firstName" TEXT, "lastName" TEXT, "email" TEXT)`;
13 |
14 | return {
15 | result: "Database migrations complete!",
16 | };
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/docs/2.deploy/10.runtimes/bun.md:
--------------------------------------------------------------------------------
1 | ---
2 | icon: simple-icons:bun
3 | ---
4 |
5 | # Bun
6 |
7 | > Run Nitro apps with Bun runtime.
8 |
9 | **Preset:** `bun`
10 |
11 | Nitro 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.
12 |
13 | After building with bun preset using `bun` as preset, you can run server in production using:
14 |
15 | ```bash
16 | bun run ./.output/server/index.mjs
17 | ```
18 |
19 | :read-more{to="https://bun.sh"}
20 |
--------------------------------------------------------------------------------
/test/fixture/routes/fetch.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const nitroApp = useNitroApp();
3 | return {
4 | $fetch: await fetch("/api/hey").then((r) => r.text()),
5 | "event.fetch": await event.fetch("/api/hey").then((r) => r.text()),
6 | "event.$fetch": await event.$fetch("/api/hey"),
7 | "nitroApp.localFetch": await nitroApp
8 | .localFetch("/api/hey")
9 | .then((r) => r.text()),
10 | "nitroApp.localCall": await nitroApp
11 | .localCall({ url: "/api/hey" })
12 | .then((r) => r.body),
13 | };
14 | });
15 |
--------------------------------------------------------------------------------
/test/presets/static.test.ts:
--------------------------------------------------------------------------------
1 | import fsp from "node:fs/promises";
2 | import { resolve } from "pathe";
3 | import { describe, expect, it } from "vitest";
4 | import { setupTest } from "../tests";
5 |
6 | describe("nitro:preset:static", async () => {
7 | const ctx = await setupTest("static");
8 | it("should not generate a server folder", async () => {
9 | const contents = await fsp.readdir(resolve(ctx.outDir));
10 | expect(contents).toMatchInlineSnapshot(`
11 | [
12 | "nitro.json",
13 | "public",
14 | ]
15 | `);
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | // Core
2 | export { createNitro } from "./nitro";
3 |
4 | // Prerender
5 | export { prerender } from "./prerender/prerender";
6 |
7 | // Dev server
8 | export { createDevServer } from "./dev/server";
9 |
10 | // Config loader
11 | export { loadOptions } from "./config/loader";
12 |
13 | // Tasks API
14 | export { runTask, listTasks } from "./task";
15 |
16 | // Build
17 | export { build } from "./build/build";
18 | export { copyPublicAssets } from "./build/assets";
19 | export { prepare } from "./build/prepare";
20 | export { writeTypes } from "./build/types";
21 |
--------------------------------------------------------------------------------
/test/fixture/routes/prerender-custom.html.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler((event) => {
2 | const links = ["/api/hello", "/api/param/foo.json", "/api/param/foo.css"];
3 |
4 | return `
5 |
6 |
7 |
8 | Prerendered routes test
9 |
10 |
11 | Prerendered routes test #2:
12 |
13 | ${links.map((link) => ` - ${link}
`).join("\n")}
14 |
15 |
16 | `;
17 | });
18 |
--------------------------------------------------------------------------------
/lib/meta.mjs:
--------------------------------------------------------------------------------
1 | import packageJson from "../package.json" with { type: "json" };
2 |
3 | export const version = packageJson.version;
4 |
5 | export const compatibilityChanges = [
6 | {
7 | from: "2024-05-07",
8 | platform: "netlify",
9 | description: "Netlify functions v2",
10 | },
11 | {
12 | from: "2024-09-19",
13 | platform: "cloudflare",
14 | description: "Static assets support for cloudflare-module preset",
15 | },
16 | {
17 | from: "2025-01-30",
18 | platform: "deno",
19 | description: "Deno v2 Node.js compatibility",
20 | },
21 | ];
22 |
--------------------------------------------------------------------------------
/src/build/prepare.ts:
--------------------------------------------------------------------------------
1 | import fsp from "node:fs/promises";
2 | import type { Nitro } from "nitro/types";
3 |
4 | export async function prepare(nitro: Nitro) {
5 | await prepareDir(nitro.options.output.dir);
6 | if (!nitro.options.noPublicDir) {
7 | await prepareDir(nitro.options.output.publicDir);
8 | }
9 | if (!nitro.options.static) {
10 | await prepareDir(nitro.options.output.serverDir);
11 | }
12 | }
13 |
14 | async function prepareDir(dir: string) {
15 | await fsp.rm(dir, { recursive: true, force: true });
16 | await fsp.mkdir(dir, { recursive: true });
17 | }
18 |
--------------------------------------------------------------------------------
/src/presets/_utils/preset.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from "node:url";
2 | import type { NitroPreset, NitroPresetMeta } from "nitro/types";
3 |
4 | export function defineNitroPreset<
5 | P extends NitroPreset,
6 | M extends NitroPresetMeta,
7 | >(preset: P, meta?: M): P & { _meta: NitroPresetMeta } {
8 | if (
9 | meta?.url &&
10 | typeof preset !== "function" &&
11 | preset.entry &&
12 | preset.entry.startsWith(".")
13 | ) {
14 | preset.entry = fileURLToPath(new URL(preset.entry, meta.url));
15 | }
16 | return { ...preset, _meta: meta } as P & { _meta: M };
17 | }
18 |
--------------------------------------------------------------------------------
/test/fixture/routes/static-flags.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | return {
3 | dev: [process.dev, import.meta.dev],
4 | preset: [process.preset, import.meta.preset],
5 | prerender: [process.prerender, import.meta.prerender],
6 | server: [process.server, import.meta.server],
7 | client: [process.client, import.meta.client],
8 | nitro: [process.nitro, import.meta.nitro],
9 | "versions.nitro": [process.versions.nitro, import.meta.versions.nitro],
10 | "versions?.nitro": [process.versions?.nitro, import.meta.versions?.nitro],
11 | };
12 | });
13 |
--------------------------------------------------------------------------------
/src/cli/commands/prepare.ts:
--------------------------------------------------------------------------------
1 | import { defineCommand } from "citty";
2 | import { createNitro, writeTypes } from "nitro";
3 | import { resolve } from "pathe";
4 | import { commonArgs } from "../common";
5 |
6 | export default defineCommand({
7 | meta: {
8 | name: "prepare",
9 | description: "Generate types for the project",
10 | },
11 | args: {
12 | ...commonArgs,
13 | },
14 | async run({ args }) {
15 | const rootDir = resolve((args.dir || args._dir || ".") as string);
16 | const nitro = await createNitro({ rootDir });
17 | await writeTypes(nitro);
18 | },
19 | });
20 |
--------------------------------------------------------------------------------
/test/fixture/api/db.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(async () => {
2 | const db = useDatabase();
3 |
4 | // Create users table
5 | await db.sql`DROP TABLE IF EXISTS users`;
6 | await db.sql`CREATE TABLE IF NOT EXISTS users ("id" TEXT PRIMARY KEY, "firstName" TEXT, "lastName" TEXT, "email" TEXT)`;
7 |
8 | // Add a new user
9 | const userId = "1001";
10 | await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;
11 |
12 | // Query for users
13 | const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;
14 |
15 | return {
16 | rows,
17 | };
18 | });
19 |
--------------------------------------------------------------------------------
/src/presets/winterjs/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const winterjs = defineNitroPreset(
4 | {
5 | extends: "base-worker",
6 | entry: "./runtime/winterjs",
7 | minify: false,
8 | serveStatic: "inline",
9 | wasm: {
10 | lazy: true,
11 | },
12 | commands: {
13 | preview:
14 | "wasmer run wasmer/winterjs --forward-host-env --net --mapdir app:./ app/server/index.mjs",
15 | },
16 | },
17 | {
18 | name: "winterjs" as const,
19 | url: import.meta.url,
20 | }
21 | );
22 |
23 | export default [winterjs] as const;
24 |
--------------------------------------------------------------------------------
/test/scripts/gen-fixture-types.ts:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from "mlly";
2 | import { createNitro, writeTypes } from "nitro";
3 | import { resolve } from "pathe";
4 | import { scanHandlers } from "../../src/scan";
5 |
6 | const prepare = async () => {
7 | const fixtureDir = fileURLToPath(new URL("../fixture", import.meta.url).href);
8 |
9 | const nitro = await createNitro({
10 | rootDir: fixtureDir,
11 | serveStatic: true,
12 | output: { dir: resolve(fixtureDir, ".output", "types") },
13 | });
14 |
15 | await scanHandlers(nitro);
16 | await writeTypes(nitro);
17 | };
18 |
19 | prepare();
20 |
--------------------------------------------------------------------------------
/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import unjs from "eslint-config-unjs";
2 |
3 | export default unjs({
4 | ignores: [
5 | "**/.output",
6 | "**/.nitro",
7 | "**/.netlify",
8 | "**/.vercel",
9 | "**/.nuxt",
10 | "**/*.gen.*",
11 | "**/dist",
12 | ],
13 | rules: {
14 | "unicorn/no-null": 0,
15 | "no-undef": 0,
16 | "@typescript-eslint/no-unused-vars": 0,
17 | "unicorn/filename-case": 0,
18 | "unicorn/consistent-function-scoping": 0,
19 | "@typescript-eslint/no-empty-object-type": 0,
20 | "unicorn/no-empty-file": 0,
21 | "unicorn/prefer-ternary": 0,
22 | },
23 | });
24 |
--------------------------------------------------------------------------------
/src/config/resolvers/error.ts:
--------------------------------------------------------------------------------
1 | import { runtimeDir } from "nitro/runtime/meta";
2 | import type { NitroOptions } from "nitro/types";
3 | import { join } from "pathe";
4 |
5 | export async function resolveErrorOptions(options: NitroOptions) {
6 | if (!options.errorHandler) {
7 | options.errorHandler = [];
8 | } else if (!Array.isArray(options.errorHandler)) {
9 | options.errorHandler = [options.errorHandler];
10 | }
11 |
12 | // Always add the default error handler as the last one
13 | options.errorHandler.push(
14 | join(runtimeDir, `internal/error/${options.dev ? "dev" : "prod"}`)
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/docs/2.deploy/10.runtimes/deno.md:
--------------------------------------------------------------------------------
1 | ---
2 | icon: simple-icons:deno
3 | ---
4 |
5 | # Deno
6 |
7 | > Run Nitro apps with [Deno](https://deno.com/) runtime.
8 |
9 | **Preset:** `deno_server`
10 |
11 | You can build your Nitro server using Node.js to run within [Deno Runtime](https://deno.com/runtime) in a custom server.
12 |
13 | ```bash
14 | # Build with the deno NITRO preset
15 | NITRO_PRESET=deno_server npm run build
16 |
17 | # Start production server
18 | deno run --unstable --allow-net --allow-read --allow-env .output/server/index.ts
19 | ```
20 |
21 | ## Deno Deploy
22 |
23 | :read-more{to="/deploy/providers/deno-deploy"}
24 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## ⚠️ Reporting a Vulnerability
4 |
5 | To report a vulnerability, please send an email to [security+nitro@unjs.io](mailto:security+nitro@unjs.io) or submit it for a bounty via [Huntr](https://huntr.dev/bounties/disclose/?target=https://github.com/nitrojs/nitro).
6 |
7 | All security vulnerabilities will be promptly verified and addressed.
8 |
9 | We recommend to regularly upgrade and publish with the latest versions of used packages and sub-dependencies by maintaining lock files (`yarn.lock`, `package-lock.json` and `pnpm-lock.yaml`) in order to ensure your application remains as secure as possible.
10 |
--------------------------------------------------------------------------------
/src/cli/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import { defineCommand, runMain } from "citty";
3 | import { version as nitroVersion } from "nitro/meta";
4 |
5 | const main = defineCommand({
6 | meta: {
7 | name: "nitro",
8 | description: "Nitro CLI",
9 | version: nitroVersion,
10 | },
11 | subCommands: {
12 | dev: () => import("./commands/dev").then((r) => r.default),
13 | build: () => import("./commands/build").then((r) => r.default),
14 | prepare: () => import("./commands/prepare").then((r) => r.default),
15 | task: () => import("./commands/task").then((r) => r.default),
16 | },
17 | });
18 |
19 | runMain(main);
20 |
--------------------------------------------------------------------------------
/examples/database/routes/index.ts:
--------------------------------------------------------------------------------
1 | export default defineEventHandler(async () => {
2 | const db = useDatabase();
3 |
4 | // Create users table
5 | await db.sql`DROP TABLE IF EXISTS users`;
6 | await db.sql`CREATE TABLE IF NOT EXISTS users ("id" TEXT PRIMARY KEY, "firstName" TEXT, "lastName" TEXT, "email" TEXT)`;
7 |
8 | // Add a new user
9 | const userId = String(Math.round(Math.random() * 10_000));
10 | await db.sql`INSERT INTO users VALUES (${userId}, 'John', 'Doe', '')`;
11 |
12 | // Query for users
13 | const { rows } = await db.sql`SELECT * FROM users WHERE id = ${userId}`;
14 |
15 | return {
16 | rows,
17 | };
18 | });
19 |
--------------------------------------------------------------------------------
/src/presets/_nitro/base-worker.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const baseWorker = defineNitroPreset(
4 | {
5 | entry: null as any, // Abstract
6 | node: false,
7 | minify: true,
8 | noExternals: true,
9 | rollupConfig: {
10 | output: {
11 | format: "iife",
12 | generatedCode: {
13 | symbols: true,
14 | },
15 | },
16 | },
17 | inlineDynamicImports: true, // iffe does not support code-splitting
18 | },
19 | {
20 | name: "base-worker" as const,
21 | url: import.meta.url,
22 | }
23 | );
24 |
25 | export default [baseWorker] as const;
26 |
--------------------------------------------------------------------------------
/src/runtime/internal/database.ts:
--------------------------------------------------------------------------------
1 | import type { Database } from "db0";
2 | import { createDatabase } from "db0";
3 | import { connectionConfigs } from "#nitro-internal-virtual/database";
4 |
5 | const instances: Record = Object.create(null);
6 |
7 | export function useDatabase(name = "default"): Database {
8 | if (instances[name]) {
9 | return instances[name];
10 | }
11 | if (!connectionConfigs[name]) {
12 | throw new Error(`Database connection "${name}" not configured.`);
13 | }
14 | return (instances[name] = createDatabase(
15 | connectionConfigs[name].connector(connectionConfigs[name].options || {})
16 | ));
17 | }
18 |
--------------------------------------------------------------------------------
/docs/2.deploy/20.providers/zeabur.md:
--------------------------------------------------------------------------------
1 | # Zeabur
2 |
3 | > Deploy Nitro apps to [Zeabur](https://zeabur.com).
4 |
5 | **Preset:** `zeabur`
6 |
7 | :read-more{title="Zeabur" to="https://zeabur.com"}
8 |
9 | ::note
10 | Integration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).
11 | ::
12 |
13 | ## Deploy using git
14 |
15 | 1. Push your code to your git repository (Currently only GitHub supported).
16 | 2. [Import your project](https://zeabur.com/docs/get-started) into Zeabur.
17 | 3. Zeabur will detect that you are using Nitro and will enable the correct settings for your deployment.
18 | 4. Your application is deployed!
19 |
--------------------------------------------------------------------------------
/src/presets/vercel/runtime/vercel.ts:
--------------------------------------------------------------------------------
1 | import "#nitro-internal-pollyfills";
2 | import { useNitroApp } from "nitro/runtime";
3 |
4 | import { type NodeListener, toNodeListener } from "h3";
5 | import { parseQuery } from "ufo";
6 |
7 | const nitroApp = useNitroApp();
8 |
9 | const handler = toNodeListener(nitroApp.h3App);
10 |
11 | const listener: NodeListener = function (req, res) {
12 | const query = req.headers["x-now-route-matches"] as string;
13 | if (query) {
14 | const { url } = parseQuery(query);
15 | if (url) {
16 | req.url = url as string;
17 | }
18 | }
19 | return handler(req, res);
20 | };
21 |
22 | export default listener;
23 |
--------------------------------------------------------------------------------
/lib/runtime-meta.mjs:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from "node:url";
2 |
3 | export const pkgDir = fileURLToPath(new URL("..", import.meta.url));
4 |
5 | export const runtimeDir = fileURLToPath(
6 | new URL("../dist/runtime/", import.meta.url)
7 | );
8 |
9 | export const runtimeDependencies = [
10 | "h3",
11 | "cookie-es",
12 | "defu",
13 | "destr",
14 | "hookable",
15 | "iron-webcrypto",
16 | "klona",
17 | "node-mock-http",
18 | "ofetch",
19 | "ohash",
20 | "pathe",
21 | "radix3",
22 | "scule",
23 | "ufo",
24 | "db0",
25 | "std-env",
26 | "uncrypto",
27 | "unctx",
28 | "unenv",
29 | "unstorage",
30 | "crossws",
31 | "croner",
32 | ];
33 |
--------------------------------------------------------------------------------
/src/presets/aws-lambda/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 | export type { AwsLambdaOptions as PresetOptions } from "./types";
3 |
4 | const awsLambda = defineNitroPreset(
5 | {
6 | entry: "./runtime/aws-lambda",
7 | awsLambda: {
8 | streaming: false,
9 | },
10 | hooks: {
11 | "rollup:before": (nitro, rollupConfig) => {
12 | if (nitro.options.awsLambda.streaming) {
13 | (rollupConfig.input as string) += "-streaming";
14 | }
15 | },
16 | },
17 | },
18 | {
19 | name: "aws-lambda" as const,
20 | url: import.meta.url,
21 | }
22 | );
23 |
24 | export default [awsLambda] as const;
25 |
--------------------------------------------------------------------------------
/src/presets/node/runtime/node-middleware.ts:
--------------------------------------------------------------------------------
1 | import "#nitro-internal-pollyfills";
2 | import { toNodeListener } from "h3";
3 | import { useNitroApp } from "nitro/runtime";
4 | import {
5 | startScheduleRunner,
6 | trapUnhandledNodeErrors,
7 | } from "nitro/runtime/internal";
8 |
9 | const nitroApp = useNitroApp();
10 |
11 | export const middleware = toNodeListener(nitroApp.h3App);
12 |
13 | /** @experimental */
14 | export const websocket = import.meta._websocket
15 | ? nitroApp.h3App.websocket
16 | : undefined;
17 |
18 | // Trap unhandled errors
19 | trapUnhandledNodeErrors();
20 |
21 | // Scheduled tasks
22 | if (import.meta._tasks) {
23 | startScheduleRunner();
24 | }
25 |
--------------------------------------------------------------------------------
/src/presets/zerops/preset.ts:
--------------------------------------------------------------------------------
1 | import { defineNitroPreset } from "../_utils/preset";
2 |
3 | const zerops = defineNitroPreset(
4 | {
5 | extends: "node-server",
6 | serveStatic: true,
7 | },
8 | {
9 | name: "zerops" as const,
10 | url: import.meta.url,
11 | }
12 | );
13 |
14 | const zeropsStatic = defineNitroPreset(
15 | {
16 | extends: "static",
17 | output: {
18 | dir: "{{ rootDir }}/.zerops/output",
19 | publicDir: "{{ output.dir }}/static",
20 | },
21 | },
22 | {
23 | name: "zerops-static" as const,
24 | url: import.meta.url,
25 | static: true,
26 | }
27 | );
28 |
29 | export default [zerops, zeropsStatic] as const;
30 |
--------------------------------------------------------------------------------
/src/config/resolvers/builder.ts:
--------------------------------------------------------------------------------
1 | import type { NitroOptions } from "nitro/types";
2 |
3 | export async function resolveBuilder(options: NitroOptions) {
4 | if (!options.builder) {
5 | options.builder = (process.env.NITRO_BUILDER as any) || "rollup";
6 | }
7 |
8 | if (options.builder === "rolldown") {
9 | try {
10 | await import("rolldown");
11 | } catch {
12 | throw new Error(
13 | `Builder "rolldown" is not available. Make sure to install "rolldown" package.`
14 | );
15 | }
16 | }
17 |
18 | if (!["rollup", "rolldown"].includes(options.builder!)) {
19 | throw new Error(`Builder "${options.builder}" is not supported.`);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/automd.config.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | input: ["README.md", "docs/**/*.md"],
3 | generators: {
4 | compatDate: {
5 | async generate(ctx) {
6 | const { compatibilityChanges } = await import("./lib/meta.mjs");
7 |
8 | const table = [
9 | "| Compatibility date | Platform | Description |",
10 | "|------|----------|-------------|",
11 | ...compatibilityChanges.map(
12 | (change) =>
13 | `| **≥ ${change.from}** | ${change.platform} | ${change.description} |`
14 | ),
15 | ];
16 |
17 | return {
18 | contents: table.join("\n"),
19 | };
20 | },
21 | },
22 | },
23 | };
24 |
--------------------------------------------------------------------------------
/src/config/update.ts:
--------------------------------------------------------------------------------
1 | import consola from "consola";
2 | import type { Nitro, NitroDynamicConfig } from "nitro/types";
3 | import { normalizeRouteRules } from "./resolvers/route-rules";
4 | import { normalizeRuntimeConfig } from "./resolvers/runtime-config";
5 |
6 | export async function updateNitroConfig(
7 | nitro: Nitro,
8 | config: NitroDynamicConfig
9 | ) {
10 | nitro.options.routeRules = normalizeRouteRules(
11 | config.routeRules ? config : nitro.options
12 | );
13 | nitro.options.runtimeConfig = normalizeRuntimeConfig(
14 | config.runtimeConfig ? config : nitro.options
15 | );
16 | await nitro.hooks.callHook("rollup:reload");
17 | consola.success("Nitro config hot reloaded!");
18 | }
19 |
--------------------------------------------------------------------------------
/src/presets/_unenv/preset-deno.ts:
--------------------------------------------------------------------------------
1 | import type { Preset } from "unenv";
2 | import { builtnNodeModules } from "./node-compat/deno";
3 |
4 | // https://platform-node-compat.deno.dev/
5 | // https://platform-node-compat.netlify.app/
6 |
7 | export const unenvDenoPreset: Preset = {
8 | meta: {
9 | name: "nitro-deno",
10 | url: import.meta.url,
11 | },
12 | external: builtnNodeModules.map((m) => `node:${m}`),
13 | alias: {
14 | // (native)
15 | ...Object.fromEntries(
16 | [...builtnNodeModules, "sys"].flatMap((m) => [
17 | [m, `node:${m}`],
18 | [`node:${m}`, `node:${m}`],
19 | ])
20 | ),
21 | },
22 | inject: {
23 | performance: false,
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/src/runtime/internal/index.ts:
--------------------------------------------------------------------------------
1 | // Limited INTERNAL exports used by the presets runtime
2 | // Please don't use these in your project code!
3 |
4 | export {
5 | trapUnhandledNodeErrors,
6 | normalizeCookieHeader,
7 | requestHasBody,
8 | joinHeaders,
9 | toBuffer,
10 | } from "./utils";
11 |
12 | export {
13 | normalizeLambdaIncomingHeaders,
14 | normalizeLambdaOutgoingHeaders,
15 | normalizeLambdaOutgoingBody,
16 | } from "./utils.lambda";
17 |
18 | export { startScheduleRunner, runCronTasks } from "./task";
19 | export { getAzureParsedCookiesFromHeaders } from "./utils.azure";
20 | export { getGracefulShutdownConfig, setupGracefulShutdown } from "./shutdown";
21 | export { getRouteRulesForPath } from "./route-rules";
22 |
--------------------------------------------------------------------------------
/examples/websocket/routes/_ws.ts:
--------------------------------------------------------------------------------
1 | export default defineWebSocketHandler({
2 | open(peer) {
3 | peer.send({ user: "server", message: `Welcome ${peer}!` });
4 | peer.publish("chat", { user: "server", message: `${peer} joined!` });
5 | peer.subscribe("chat");
6 | },
7 | message(peer, message) {
8 | if (message.text().includes("ping")) {
9 | peer.send({ user: "server", message: "pong" });
10 | } else {
11 | const msg = {
12 | user: peer.toString(),
13 | message: message.toString(),
14 | };
15 | peer.send(msg); // echo
16 | peer.publish("chat", msg);
17 | }
18 | },
19 | close(peer) {
20 | peer.publish("chat", { user: "server", message: `${peer} left!` });
21 | },
22 | });
23 |
--------------------------------------------------------------------------------
/src/build/plugins/replace.ts:
--------------------------------------------------------------------------------
1 | import _replace from "@rollup/plugin-replace";
2 | import type { RollupReplaceOptions } from "@rollup/plugin-replace";
3 | import type { Plugin } from "rollup";
4 |
5 | const NO_REPLACE_RE = /ROLLUP_NO_REPLACE/;
6 |
7 | export function replace(options: RollupReplaceOptions): Plugin {
8 | const _plugin = _replace(options);
9 | return {
10 | ..._plugin,
11 | // https://github.com/rollup/plugins/blob/master/packages/replace/src/index.js#L94
12 | renderChunk(code, chunk, options) {
13 | if (!NO_REPLACE_RE.test(code)) {
14 | // prettier-ignore
15 | // @ts-ignore
16 | return (_plugin.renderChunk as () => any).call(this, code, chunk, options );
17 | }
18 | },
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // https://code.visualstudio.com/docs/devcontainers/containers
2 | // https://containers.dev/implementors/json_reference/
3 | {
4 | "name": "nitro-devcontainer",
5 | "forwardPorts": [3000],
6 | "image": "node:22",
7 | "features": {},
8 | "customizations": {
9 | "vscode": {
10 | "settings": {},
11 | "extensions": [
12 | "ms-azuretools.vscode-docker",
13 | "dbaeumer.vscode-eslint",
14 | "github.vscode-github-actions",
15 | "esbenp.prettier-vscode"
16 | ]
17 | }
18 | },
19 | "postStartCommand": "npm i -fg corepack && corepack enable && pnpm install && pnpm build --stub",
20 | "mounts": ["type=volume,target=${containerWorkspaceFolder}/node_modules"]
21 | }
22 |
--------------------------------------------------------------------------------
/test/fixture/routes/modules.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | import depA from "@fixture/nitro-dep-a";
3 | // @ts-ignore
4 | import depB from "@fixture/nitro-dep-b";
5 | // @ts-ignore
6 | import depLib from "@fixture/nitro-lib";
7 | // @ts-ignore
8 | import subpathLib from "@fixture/nitro-lib/subpath";
9 | // @ts-ignore
10 | import extraUtils from "@fixture/nitro-utils/extra";
11 | // @ts-ignore
12 | import extraUtilsAbsolute from "#fixture-nitro-utils-extra-absolute";
13 |
14 | export default defineEventHandler(() => {
15 | return {
16 | depA, // expected to all be 1.0.0
17 | depB, // expected to all be 2.0.1
18 | depLib, // expected to all be 2.0.0
19 | subpathLib, // expected to 2.0.0
20 | extraUtils,
21 | extraUtilsAbsolute,
22 | };
23 | });
24 |
--------------------------------------------------------------------------------
/test/fixture/routes/assets/all.ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const serverAssets = useStorage("assets/server");
3 |
4 | const keys = await serverAssets.getKeys();
5 | const items = await Promise.all(
6 | keys.map(async (key) => {
7 | return {
8 | key,
9 | meta: await serverAssets.getMeta(key),
10 | data: await serverAssets.getItem(key).then((r) =>
11 | // prettier-ignore
12 | typeof r === "string" ? r.slice(0, 32) : (isPureObject(r) ? r : ``)
13 | ),
14 | };
15 | })
16 | );
17 |
18 | return items;
19 | });
20 |
21 | function isPureObject(value) {
22 | return (
23 | value !== null && typeof value === "object" && value.constructor === Object
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/docs/2.deploy/20.providers/cleavr.md:
--------------------------------------------------------------------------------
1 | # Cleavr
2 |
3 | > Deploy Nitro apps to Cleavr.
4 |
5 | **Preset:** `cleavr`
6 |
7 | :read-more{title="cleavr.io" to="https://cleavr.io"}
8 |
9 | ::note
10 | Integration with this provider is possible with [zero configuration](/deploy/#zero-config-providers).
11 | ::
12 |
13 | ## Set up your web app
14 |
15 | In your project, set Nitro preset to `cleavr`.
16 |
17 | ```js
18 | export default {
19 | nitro: {
20 | preset: 'cleavr'
21 | }
22 | }
23 | ```
24 |
25 | Push changes to your code repository.
26 |
27 | **In your Cleavr panel:**
28 |
29 | 1. Provision a new server
30 | 2. Add a website, selecting **Nuxt 3** as the app type
31 | 3. In web app > settings > Code Repo, point to your project's code repository
32 |
33 | You're now all set to deploy your project!
34 |
--------------------------------------------------------------------------------
/.github/workflows-disabled/codeql.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: ["main"]
6 | pull_request:
7 | branches: ["main"]
8 |
9 | jobs:
10 | analyze:
11 | name: Analyze
12 | runs-on: "ubuntu-latest"
13 | timeout-minutes: 360
14 | permissions:
15 | actions: read
16 | contents: read
17 | security-events: write
18 |
19 | strategy:
20 | fail-fast: false
21 |
22 | steps:
23 | - name: Checkout repository
24 | uses: actions/checkout@v4
25 |
26 | - name: Initialize CodeQL
27 | uses: github/codeql-action/init@v2
28 | with:
29 | languages: "javascript"
30 |
31 | - name: Perform CodeQL Analysis
32 | uses: github/codeql-action/analyze@v2
33 | with:
34 | category: "/language:javascript"
35 |
--------------------------------------------------------------------------------
/.github/workflows/autofix.yml:
--------------------------------------------------------------------------------
1 | name: autofix.ci # needed to securely identify the workflow
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches:
7 | - v2
8 | - v3
9 |
10 | permissions:
11 | contents: read
12 |
13 | jobs:
14 | autofix:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v4
18 | - run: npm i -g --force corepack && corepack enable
19 | - uses: actions/setup-node@v4
20 | with:
21 | node-version: 22
22 | cache: "pnpm"
23 | - run: pnpm install
24 | - run: pnpm stub
25 | - run: pnpm gen-presets
26 | - name: Fix lint issues
27 | run: npm run lint:fix
28 | - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
29 | with:
30 | commit-message: "chore: apply automated updates"
31 |
--------------------------------------------------------------------------------
/test/fixture/routes/assets/[id].ts:
--------------------------------------------------------------------------------
1 | export default eventHandler(async (event) => {
2 | const serverAssets = useStorage("assets/server");
3 |
4 | const id = event.context.params.id;
5 |
6 | if (!(await serverAssets.hasItem(id))) {
7 | throw createError({ message: `Asset ${id} not found`, statusCode: 404 });
8 | }
9 |
10 | const meta = (await serverAssets.getMeta(
11 | event.context.params.id
12 | )) as unknown as { type: string; etag: string; mtime: string };
13 |
14 | if (meta.type) {
15 | setResponseHeader(event, "content-type", meta.type);
16 | }
17 |
18 | if (meta.etag) {
19 | setResponseHeader(event, "etag", meta.etag);
20 | }
21 |
22 | if (meta.mtime) {
23 | setResponseHeader(event, "last-modified", meta.mtime);
24 | }
25 |
26 | return serverAssets.getItemRaw(event.context.params.id);
27 | });
28 |
--------------------------------------------------------------------------------
/src/config/resolvers/database.ts:
--------------------------------------------------------------------------------
1 | import type { NitroOptions } from "nitro/types";
2 |
3 | export async function resolveDatabaseOptions(options: NitroOptions) {
4 | if (options.experimental.database && options.imports) {
5 | options.imports.presets.push({
6 | from: "nitro/runtime/internal/database",
7 | imports: ["useDatabase"],
8 | });
9 | if (options.dev && !options.database && !options.devDatabase) {
10 | options.devDatabase = {
11 | default: {
12 | connector: "sqlite",
13 | options: {
14 | cwd: options.rootDir,
15 | },
16 | },
17 | };
18 | } else if (options.node && !options.database) {
19 | options.database = {
20 | default: {
21 | connector: "sqlite",
22 | options: {},
23 | },
24 | };
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/docs/2.deploy/20.providers/stormkit.md:
--------------------------------------------------------------------------------
1 | # StormKit
2 |
3 | > Deploy Nitro apps to StormKit.
4 |
5 | **Preset:** `stormkit`
6 |
7 | :read-more{title="Stormkit" to="https://www.stormkit.io"}
8 |
9 | ::note
10 | Integration with [Stormkit](https://www.stormkit.io/) is possible with [zero configuration](/deploy#zero-config-providers).
11 | ::
12 |
13 | ## Setup
14 |
15 | Follow the steps to [create a new app](https://app.stormkit.io/apps/new) on Stormkit.
16 |
17 | 
18 |
19 | ## Deployment
20 |
21 | By 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`.
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/src/types/runtime/task.ts:
--------------------------------------------------------------------------------
1 | type MaybePromise = T | Promise;
2 |
3 | /** @experimental */
4 | export interface TaskContext {}
5 |
6 | /** @experimental */
7 | export interface TaskPayload {
8 | [key: string]: unknown;
9 | }
10 |
11 | /** @experimental */
12 | export interface TaskMeta {
13 | name?: string;
14 | description?: string;
15 | }
16 |
17 | /** @experimental */
18 | export interface TaskEvent {
19 | name: string;
20 | payload: TaskPayload;
21 | context: TaskContext;
22 | }
23 |
24 | /** @experimental */
25 | export interface TaskResult