nitro 3.0.1-alpha.2 → 3.0.260415-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +2 -2
  3. package/dist/THIRD-PARTY-LICENSES.md +1646 -0
  4. package/dist/_build/common.mjs +7261 -3812
  5. package/dist/_build/rolldown.mjs +32 -42
  6. package/dist/_build/rollup.mjs +28 -48
  7. package/dist/_build/vite.build.mjs +10 -10
  8. package/dist/_chunks/nitro.mjs +102 -327
  9. package/dist/_chunks/nitro2.mjs +8 -9
  10. package/dist/_chunks/nitro3.mjs +136 -0
  11. package/dist/_chunks/nitro4.mjs +127 -0
  12. package/dist/_chunks/utils.mjs +40 -29
  13. package/dist/_common.mjs +13 -25
  14. package/dist/_dev.d.mts +0 -3
  15. package/dist/{_chunks/dev.mjs → _dev.mjs} +132 -330
  16. package/dist/_libs/_.mjs +2 -0
  17. package/dist/_libs/_2.mjs +2 -0
  18. package/dist/_libs/_3.mjs +2 -0
  19. package/dist/_libs/_4.mjs +2 -0
  20. package/dist/_libs/_5.mjs +2 -0
  21. package/dist/_libs/_6.mjs +2 -0
  22. package/dist/_libs/_7.mjs +2 -0
  23. package/dist/_libs/c12+rc9.mjs +814 -0
  24. package/dist/_libs/{c12+giget+readdirp+chokidar.d.mts → c12+readdirp+chokidar.d.mts} +49 -40
  25. package/dist/_libs/citty.mjs +142 -41
  26. package/dist/_libs/commondir+is-reference.mjs +60 -56
  27. package/dist/_libs/compatx.d.mts +0 -2
  28. package/dist/_libs/compatx.mjs +1 -4
  29. package/dist/_libs/esbuild.d.mts +0 -1
  30. package/dist/_libs/escape-string-regexp.mjs +1 -4
  31. package/dist/_libs/{pluginutils+plugin-commonjs.d.mts → estree+pluginutils.d.mts} +0 -5
  32. package/dist/_libs/estree-walker.mjs +4 -92
  33. package/dist/_libs/exsolve.d.mts +1 -0
  34. package/dist/_libs/hasown+resolve+deepmerge.mjs +160 -246
  35. package/dist/_libs/httpxy.d.mts +20 -13
  36. package/dist/_libs/httpxy.mjs +519 -95
  37. package/dist/_libs/js-tokens.d.mts +1 -0
  38. package/dist/_libs/klona.mjs +1 -4
  39. package/dist/_libs/magic-string.d.mts +0 -2
  40. package/dist/_libs/mlly.d.mts +0 -2
  41. package/dist/_libs/nypm+tinyexec.mjs +822 -0
  42. package/dist/_libs/perfect-debounce.mjs +68 -0
  43. package/dist/_libs/pkg-types.d.mts +0 -3
  44. package/dist/_libs/plugin-alias.mjs +1 -5
  45. package/dist/_libs/plugin-inject.mjs +1 -7
  46. package/dist/_libs/plugin-json.mjs +1 -5
  47. package/dist/_libs/pluginutils.mjs +3 -35
  48. package/dist/_libs/readdirp+chokidar.mjs +187 -365
  49. package/dist/_libs/remapping.mjs +1 -5
  50. package/dist/_libs/resolve-uri+gen-mapping.mjs +15 -53
  51. package/dist/_libs/rou3.d.mts +1 -4
  52. package/dist/_libs/rou3.mjs +223 -78
  53. package/dist/_libs/std-env.d.mts +8 -2
  54. package/dist/_libs/strip-literal.d.mts +1 -0
  55. package/dist/_libs/tsconfck.mjs +21 -334
  56. package/dist/_libs/ultrahtml.mjs +3 -16
  57. package/dist/_libs/unimport+unplugin.mjs +244 -388
  58. package/dist/_libs/unplugin+unimport.d.mts +5 -15
  59. package/dist/_libs/unwasm.d.mts +0 -3
  60. package/dist/_presets.mjs +576 -488
  61. package/dist/builder.d.mts +5 -25
  62. package/dist/builder.mjs +3 -8
  63. package/dist/cli/_chunks/build.mjs +22 -25
  64. package/dist/cli/_chunks/common.mjs +1 -4
  65. package/dist/cli/_chunks/deploy.mjs +37 -0
  66. package/dist/cli/_chunks/dev.mjs +6 -11
  67. package/dist/cli/_chunks/docs.mjs +28 -0
  68. package/dist/cli/_chunks/list.mjs +4 -8
  69. package/dist/cli/_chunks/prepare.mjs +2 -6
  70. package/dist/cli/_chunks/preview.mjs +48 -0
  71. package/dist/cli/_chunks/run.mjs +7 -11
  72. package/dist/cli/_chunks/task.mjs +1 -5
  73. package/dist/cli/index.mjs +5 -6
  74. package/dist/docs/0.docs/0.index/index.md +56 -0
  75. package/dist/docs/0.docs/1.quick-start.md +110 -0
  76. package/dist/docs/0.docs/10.lifecycle.md +204 -0
  77. package/dist/docs/0.docs/11.openapi.md +291 -0
  78. package/dist/docs/0.docs/12.plugins.md +164 -0
  79. package/dist/docs/0.docs/13.tasks.md +277 -0
  80. package/dist/docs/0.docs/14.websocket.md +386 -0
  81. package/dist/docs/0.docs/15.migration.md +213 -0
  82. package/dist/docs/0.docs/16.nightly.md +31 -0
  83. package/dist/docs/0.docs/2.renderer.md +322 -0
  84. package/dist/docs/0.docs/3.routing.md +711 -0
  85. package/dist/docs/0.docs/4.server-entry.md +239 -0
  86. package/dist/docs/0.docs/5.cache.md +408 -0
  87. package/dist/docs/0.docs/6.storage.md +261 -0
  88. package/dist/docs/0.docs/7.assets.md +166 -0
  89. package/dist/docs/0.docs/8.configuration.md +256 -0
  90. package/dist/docs/0.docs/9.database.md +185 -0
  91. package/dist/docs/1.deploy/0.index/index.md +64 -0
  92. package/dist/docs/1.deploy/1.runtimes/0.node.md +63 -0
  93. package/dist/docs/1.deploy/1.runtimes/1.bun.md +15 -0
  94. package/dist/docs/1.deploy/1.runtimes/2.deno.md +19 -0
  95. package/dist/docs/1.deploy/2.providers/0.alwaysdata.md +50 -0
  96. package/dist/docs/1.deploy/2.providers/1.aws.md +47 -0
  97. package/dist/docs/1.deploy/2.providers/10.flightcontrol.md +67 -0
  98. package/dist/docs/1.deploy/2.providers/11.genezio.md +67 -0
  99. package/dist/docs/1.deploy/2.providers/12.github-pages.md +68 -0
  100. package/dist/docs/1.deploy/2.providers/13.gitlab-pages.md +37 -0
  101. package/dist/docs/1.deploy/2.providers/14.heroku.md +84 -0
  102. package/dist/docs/1.deploy/2.providers/15.iis.md +38 -0
  103. package/dist/docs/1.deploy/2.providers/16.koyeb.md +109 -0
  104. package/dist/docs/1.deploy/2.providers/17.netlify.md +47 -0
  105. package/dist/docs/1.deploy/2.providers/18.platform-sh.md +37 -0
  106. package/dist/docs/1.deploy/2.providers/19.render.md +37 -0
  107. package/dist/docs/1.deploy/2.providers/2.aws-amplify.md +81 -0
  108. package/dist/docs/1.deploy/2.providers/20.stormkit.md +24 -0
  109. package/dist/docs/1.deploy/2.providers/21.vercel.md +270 -0
  110. package/dist/docs/1.deploy/2.providers/22.zeabur.md +19 -0
  111. package/dist/docs/1.deploy/2.providers/23.zephyr.md +99 -0
  112. package/dist/docs/1.deploy/2.providers/24.zerops.md +102 -0
  113. package/dist/docs/1.deploy/2.providers/3.azure.md +72 -0
  114. package/dist/docs/1.deploy/2.providers/4.cleavr.md +33 -0
  115. package/dist/docs/1.deploy/2.providers/5.cloudflare.md +369 -0
  116. package/dist/docs/1.deploy/2.providers/6.deno-deploy.md +66 -0
  117. package/dist/docs/1.deploy/2.providers/7.digitalocean.md +46 -0
  118. package/dist/docs/1.deploy/2.providers/8.edgeone.md +20 -0
  119. package/dist/docs/1.deploy/2.providers/9.firebase.md +32 -0
  120. package/dist/docs/2.config/0.index/index.md +1221 -0
  121. package/dist/docs/3.examples/0.index/index.md +3 -0
  122. package/dist/docs/3.examples/1.api-routes.md +145 -0
  123. package/dist/docs/3.examples/10.hono.md +74 -0
  124. package/dist/docs/3.examples/11.import-alias.md +97 -0
  125. package/dist/docs/3.examples/12.middleware.md +91 -0
  126. package/dist/docs/3.examples/13.mono-jsx.md +68 -0
  127. package/dist/docs/3.examples/14.nano-jsx.md +70 -0
  128. package/dist/docs/3.examples/15.plugins.md +91 -0
  129. package/dist/docs/3.examples/16.renderer.md +113 -0
  130. package/dist/docs/3.examples/17.runtime-config.md +97 -0
  131. package/dist/docs/3.examples/18.server-fetch.md +87 -0
  132. package/dist/docs/3.examples/19.shiki.md +198 -0
  133. package/dist/docs/3.examples/2.auto-imports.md +92 -0
  134. package/dist/docs/3.examples/20.virtual-routes.md +74 -0
  135. package/dist/docs/3.examples/21.vite-nitro-plugin.md +79 -0
  136. package/dist/docs/3.examples/22.vite-rsc.md +1041 -0
  137. package/dist/docs/3.examples/23.vite-ssr-html.md +217 -0
  138. package/dist/docs/3.examples/24.vite-ssr-preact.md +247 -0
  139. package/dist/docs/3.examples/25.vite-ssr-react.md +226 -0
  140. package/dist/docs/3.examples/26.vite-ssr-solid.md +256 -0
  141. package/dist/docs/3.examples/27.vite-ssr-tsr-react.md +442 -0
  142. package/dist/docs/3.examples/28.vite-ssr-tss-react.md +444 -0
  143. package/dist/docs/3.examples/29.vite-ssr-vue-router.md +617 -0
  144. package/dist/docs/3.examples/3.cached-handler.md +81 -0
  145. package/dist/docs/3.examples/30.vite-trpc.md +335 -0
  146. package/dist/docs/3.examples/31.websocket.md +282 -0
  147. package/dist/docs/3.examples/4.custom-error-handler.md +98 -0
  148. package/dist/docs/3.examples/5.database.md +157 -0
  149. package/dist/docs/3.examples/6.elysia.md +70 -0
  150. package/dist/docs/3.examples/7.express.md +78 -0
  151. package/dist/docs/3.examples/8.fastify.md +79 -0
  152. package/dist/docs/3.examples/9.hello-world.md +68 -0
  153. package/dist/docs/README.md +86 -0
  154. package/dist/docs/index.md +121 -0
  155. package/dist/node_modules/@poppinss/dumper/build/formatters/html/main.js +8 -0
  156. package/dist/node_modules/@poppinss/dumper/package.json +1 -1
  157. package/dist/node_modules/@speed-highlight/core/dist/index.js +4 -4
  158. package/dist/node_modules/@speed-highlight/core/dist/terminal.js +2 -2
  159. package/dist/node_modules/@speed-highlight/core/package.json +1 -1
  160. package/dist/node_modules/cookie-es/dist/index.mjs +299 -250
  161. package/dist/node_modules/cookie-es/package.json +26 -23
  162. package/dist/node_modules/croner/dist/croner.js +1 -1
  163. package/dist/node_modules/croner/package.json +11 -1
  164. package/dist/node_modules/defu/dist/defu.mjs +2 -2
  165. package/dist/node_modules/defu/package.json +33 -28
  166. package/dist/node_modules/rendu/dist/_chunks/libs/cookie-es.mjs +151 -0
  167. package/dist/node_modules/rendu/dist/index.mjs +5 -112
  168. package/dist/node_modules/rendu/package.json +25 -24
  169. package/dist/node_modules/youch/build/helpers-B9BQYaS6.js +23 -0
  170. package/dist/node_modules/youch/build/index.js +204 -351
  171. package/dist/node_modules/youch/build/public/error_info/script.js +1 -1
  172. package/dist/node_modules/youch/build/public_dir-C5bujZKB.js +25 -0
  173. package/dist/node_modules/youch/build/src/templates/error_cause/main.js +44 -0
  174. package/dist/node_modules/youch/build/src/templates/error_info/main.js +72 -0
  175. package/dist/node_modules/youch/build/src/templates/error_metadata/main.js +65 -0
  176. package/dist/node_modules/youch/build/src/templates/error_stack/main.js +152 -0
  177. package/dist/node_modules/youch/build/src/templates/error_stack_source/main.js +46 -0
  178. package/dist/node_modules/youch/build/src/templates/header/main.js +24 -0
  179. package/dist/node_modules/youch/build/src/templates/layout/main.js +27 -0
  180. package/dist/node_modules/youch/package.json +35 -32
  181. package/dist/presets/_nitro/runtime/nitro-dev.mjs +12 -57
  182. package/dist/presets/_nitro/runtime/nitro-prerenderer.mjs +1 -0
  183. package/dist/presets/_nitro/runtime/service-worker.mjs +1 -2
  184. package/dist/presets/aws-lambda/runtime/_utils.mjs +6 -6
  185. package/dist/presets/aws-lambda/runtime/aws-lambda-streaming.mjs +3 -1
  186. package/dist/presets/azure/runtime/_utils.mjs +5 -5
  187. package/dist/presets/azure/runtime/azure-swa.mjs +5 -5
  188. package/dist/presets/bun/runtime/bun.mjs +9 -6
  189. package/dist/presets/cloudflare/runtime/_module-handler.mjs +1 -1
  190. package/dist/presets/cloudflare/runtime/cloudflare-durable.mjs +4 -4
  191. package/dist/presets/cloudflare/runtime/cloudflare-module.mjs +3 -3
  192. package/dist/presets/cloudflare/runtime/cloudflare-pages.mjs +2 -2
  193. package/dist/presets/cloudflare/runtime/plugin.dev.mjs +10 -21
  194. package/dist/presets/deno/runtime/deno-deploy.mjs +4 -4
  195. package/dist/presets/deno/runtime/deno-server.mjs +9 -6
  196. package/dist/presets/edgeone/runtime/edgeone.mjs +10 -0
  197. package/dist/presets/netlify/runtime/netlify-edge.mjs +2 -3
  198. package/dist/presets/netlify/runtime/netlify.mjs +1 -1
  199. package/dist/presets/node/runtime/node-cluster.mjs +5 -4
  200. package/dist/presets/node/runtime/node-middleware.mjs +1 -1
  201. package/dist/presets/node/runtime/node-server.mjs +8 -5
  202. package/dist/presets/stormkit/runtime/stormkit.mjs +1 -2
  203. package/dist/presets/vercel/runtime/cron-handler.mjs +25 -0
  204. package/dist/presets/vercel/runtime/queue-handler.mjs +21 -0
  205. package/dist/presets/vercel/runtime/vercel.node.mjs +3 -3
  206. package/dist/presets/vercel/runtime/vercel.web.mjs +3 -5
  207. package/dist/presets/winterjs/runtime/winterjs.mjs +10 -10
  208. package/dist/presets/zephyr/runtime/server.mjs +3 -0
  209. package/dist/runtime/internal/app.mjs +12 -11
  210. package/dist/runtime/internal/cache.d.mts +0 -4
  211. package/dist/runtime/internal/cache.mjs +32 -256
  212. package/dist/runtime/internal/context.d.mts +3 -1
  213. package/dist/runtime/internal/context.mjs +1 -9
  214. package/dist/runtime/internal/error/dev.d.mts +5 -4
  215. package/dist/runtime/internal/error/dev.mjs +47 -49
  216. package/dist/runtime/internal/error/hooks.d.mts +1 -1
  217. package/dist/runtime/internal/error/prod.d.mts +2 -5
  218. package/dist/runtime/internal/error/prod.mjs +19 -33
  219. package/dist/runtime/internal/error/utils.d.mts +4 -4
  220. package/dist/runtime/internal/meta.d.mts +1 -1
  221. package/dist/runtime/internal/plugin.d.mts +2 -2
  222. package/dist/runtime/internal/route-rules.d.mts +11 -4
  223. package/dist/runtime/internal/route-rules.mjs +15 -5
  224. package/dist/runtime/internal/routes/dev-tasks.d.mts +3 -2
  225. package/dist/runtime/internal/routes/dev-tasks.mjs +15 -10
  226. package/dist/runtime/internal/routes/openapi.mjs +2 -2
  227. package/dist/runtime/internal/routes/renderer-template.d.mts +1 -1
  228. package/dist/runtime/internal/routes/renderer-template.dev.d.mts +2 -1
  229. package/dist/runtime/internal/routes/scalar.mjs +3 -3
  230. package/dist/runtime/internal/routes/swagger.mjs +7 -4
  231. package/dist/runtime/internal/runtime-config.d.mts +1 -1
  232. package/dist/runtime/internal/runtime-config.mjs +2 -2
  233. package/dist/runtime/internal/static.mjs +5 -4
  234. package/dist/runtime/internal/task.d.mts +3 -1
  235. package/dist/runtime/internal/task.mjs +7 -7
  236. package/dist/runtime/internal/vite/dev-entry.mjs +6 -3
  237. package/dist/runtime/internal/vite/dev-worker.mjs +264 -0
  238. package/dist/runtime/meta.d.mts +1 -0
  239. package/dist/runtime/meta.mjs +2 -0
  240. package/dist/runtime/nitro.d.mts +2 -0
  241. package/dist/runtime/nitro.mjs +4 -2
  242. package/dist/runtime/virtual/error-handler.mjs +1 -1
  243. package/dist/runtime/virtual/renderer-template.mjs +1 -1
  244. package/dist/runtime/virtual/server-assets.d.mts +2 -1
  245. package/dist/runtime/virtual/tracing.d.mts +5 -0
  246. package/dist/runtime/virtual/tracing.mjs +1 -0
  247. package/dist/runtime/vite.d.mts +1 -1
  248. package/dist/types/index.d.mts +215 -195
  249. package/dist/types/index.mjs +1 -11
  250. package/dist/vite.d.mts +3 -8
  251. package/dist/vite.mjs +285 -253
  252. package/lib/tsconfig.json +3 -5
  253. package/package.json +97 -80
  254. package/dist/_libs/confbox.mjs +0 -2509
  255. package/dist/_libs/nypm+giget+tinyexec.mjs +0 -3603
  256. package/dist/_libs/rc9+c12+dotenv.mjs +0 -972
  257. package/dist/node_modules/hookable/dist/index.mjs +0 -266
  258. package/dist/node_modules/hookable/package.json +0 -52
  259. package/dist/node_modules/youch/build/chunk-4L7RY2JA.js +0 -42
  260. package/dist/node_modules/youch/build/chunk-7QV3D5YX.js +0 -83
  261. package/dist/node_modules/youch/build/chunk-AUGPHE32.js +0 -39
  262. package/dist/node_modules/youch/build/chunk-CM7DWJNZ.js +0 -44
  263. package/dist/node_modules/youch/build/chunk-EJH674NB.js +0 -223
  264. package/dist/node_modules/youch/build/chunk-OIJ3WD7L.js +0 -81
  265. package/dist/node_modules/youch/build/chunk-P36L72PL.js +0 -87
  266. package/dist/node_modules/youch/build/chunk-PE3GG3TN.js +0 -65
  267. package/dist/node_modules/youch/build/chunk-X53OIOJH.js +0 -70
  268. package/dist/presets/_nitro/runtime/nitro-dev.d.mts +0 -2
  269. package/dist/presets/_nitro/runtime/nitro-prerenderer.d.mts +0 -3
  270. package/dist/presets/_nitro/runtime/service-worker.d.mts +0 -2
  271. package/dist/presets/aws-amplify/runtime/aws-amplify.d.mts +0 -2
  272. package/dist/presets/aws-lambda/runtime/_utils.d.mts +0 -8
  273. package/dist/presets/aws-lambda/runtime/aws-lambda-streaming.d.mts +0 -2
  274. package/dist/presets/aws-lambda/runtime/aws-lambda.d.mts +0 -3
  275. package/dist/presets/azure/runtime/_utils.d.mts +0 -2
  276. package/dist/presets/azure/runtime/azure-swa.d.mts +0 -5
  277. package/dist/presets/bun/runtime/bun.d.mts +0 -3
  278. package/dist/presets/cloudflare/runtime/_module-handler.d.mts +0 -16
  279. package/dist/presets/cloudflare/runtime/cloudflare-durable.d.mts +0 -11
  280. package/dist/presets/cloudflare/runtime/cloudflare-module.d.mts +0 -3
  281. package/dist/presets/cloudflare/runtime/cloudflare-pages.d.mts +0 -20
  282. package/dist/presets/cloudflare/runtime/plugin.dev.d.mts +0 -3
  283. package/dist/presets/deno/runtime/deno-deploy.d.mts +0 -5
  284. package/dist/presets/deno/runtime/deno-server.d.mts +0 -3
  285. package/dist/presets/netlify/runtime/netlify-edge.d.mts +0 -3
  286. package/dist/presets/netlify/runtime/netlify.d.mts +0 -4
  287. package/dist/presets/node/runtime/node-cluster.d.mts +0 -3
  288. package/dist/presets/node/runtime/node-middleware.d.mts +0 -3
  289. package/dist/presets/node/runtime/node-server.d.mts +0 -3
  290. package/dist/presets/standard/runtime/server.d.mts +0 -3
  291. package/dist/presets/stormkit/runtime/stormkit.d.mts +0 -21
  292. package/dist/presets/vercel/runtime/isr.d.mts +0 -2
  293. package/dist/presets/vercel/runtime/vercel.node.d.mts +0 -3
  294. package/dist/presets/vercel/runtime/vercel.web.d.mts +0 -8
  295. package/dist/presets/winterjs/runtime/winterjs.d.mts +0 -2
  296. package/dist/presets/zeabur/runtime/zeabur.d.mts +0 -3
  297. package/dist/runtime/internal/vite/node-runner.mjs +0 -359
@@ -1,265 +1,41 @@
1
- import { defineHandler, handleCacheHeaders, isHTTPEvent, toResponse } from "h3";
1
+ import { defineHandler, handleCacheHeaders, toResponse } from "h3";
2
2
  import { FastResponse } from "srvx";
3
- import { parseURL } from "ufo";
4
- import { hash } from "ohash";
3
+ import { defineCachedFunction as _defineCachedFunction, defineCachedHandler as _defineCachedHandler, setStorage } from "ocache";
5
4
  import { useNitroApp } from "./app.mjs";
6
5
  import { useStorage } from "./storage.mjs";
7
- function defaultCacheOptions() {
8
- return {
9
- name: "_",
10
- base: "/cache",
11
- swr: true,
12
- maxAge: 1
13
- };
14
- }
15
- export function defineCachedFunction(fn, opts = {}) {
16
- opts = {
17
- ...defaultCacheOptions(),
18
- ...opts
19
- };
20
- const pending = {};
21
- // Normalize cache params
22
- const group = opts.group || "nitro/functions";
23
- const name = opts.name || fn.name || "_";
24
- const integrity = opts.integrity || hash([fn, opts]);
25
- const validate = opts.validate || ((entry) => entry.value !== undefined);
26
- async function get(key, resolver, shouldInvalidateCache, event) {
27
- // Use extension for key to avoid conflicting with parent namespace (foo/bar and foo/bar/baz)
28
- const cacheKey = [
29
- opts.base,
30
- group,
31
- name,
32
- key + ".json"
33
- ].filter(Boolean).join(":").replace(/:\/$/, ":index");
34
- let entry = await useStorage().getItem(cacheKey).catch((error) => {
35
- console.error(`[cache] Cache read error.`, error);
36
- useNitroApp().captureError?.(error, {
37
- event,
38
- tags: ["cache"]
39
- });
40
- }) || {};
41
- // https://github.com/nitrojs/nitro/issues/2160
42
- if (typeof entry !== "object") {
43
- entry = {};
44
- const error = new Error("Malformed data read from cache.");
45
- console.error("[cache]", error);
46
- useNitroApp().captureError?.(error, {
47
- event,
48
- tags: ["cache"]
49
- });
50
- }
51
- const ttl = (opts.maxAge ?? 0) * 1e3;
52
- if (ttl) {
53
- entry.expires = Date.now() + ttl;
54
- }
55
- const expired = shouldInvalidateCache || entry.integrity !== integrity || ttl && Date.now() - (entry.mtime || 0) > ttl || validate(entry) === false;
56
- const _resolve = async () => {
57
- const isPending = pending[key];
58
- if (!isPending) {
59
- if (entry.value !== undefined && (opts.staleMaxAge || 0) >= 0 && opts.swr === false) {
60
- // Remove cached entry to prevent using expired cache on concurrent requests
61
- entry.value = undefined;
62
- entry.integrity = undefined;
63
- entry.mtime = undefined;
64
- entry.expires = undefined;
65
- }
66
- pending[key] = Promise.resolve(resolver());
67
- }
68
- try {
69
- entry.value = await pending[key];
70
- } catch (error) {
71
- // Make sure entries that reject get removed.
72
- if (!isPending) {
73
- delete pending[key];
74
- }
75
- // Re-throw error to make sure the caller knows the task failed.
76
- throw error;
77
- }
78
- if (!isPending) {
79
- // Update mtime, integrity + validate and set the value in cache only the first time the request is made.
80
- entry.mtime = Date.now();
81
- entry.integrity = integrity;
82
- delete pending[key];
83
- if (validate(entry) !== false) {
84
- let setOpts;
85
- if (opts.maxAge && !opts.swr) {
86
- setOpts = { ttl: opts.maxAge };
87
- }
88
- const promise = useStorage().setItem(cacheKey, entry, setOpts).catch((error) => {
89
- console.error(`[cache] Cache write error.`, error);
90
- useNitroApp().captureError?.(error, {
91
- event,
92
- tags: ["cache"]
93
- });
94
- });
95
- if (typeof event?.req?.waitUntil === "function") {
96
- event.req.waitUntil(promise);
97
- }
98
- }
99
- }
100
- };
101
- const _resolvePromise = expired ? _resolve() : Promise.resolve();
102
- if (entry.value === undefined) {
103
- await _resolvePromise;
104
- } else if (expired && event && event.req.waitUntil) {
105
- event.req.waitUntil(_resolvePromise);
106
- }
107
- if (opts.swr && validate(entry) !== false) {
108
- _resolvePromise.catch((error) => {
109
- console.error(`[cache] SWR handler error.`, error);
110
- useNitroApp().captureError?.(error, {
111
- event,
112
- tags: ["cache"]
113
- });
114
- });
115
- return entry;
116
- }
117
- return _resolvePromise.then(() => entry);
6
+ let _storageReady = false;
7
+ function ensureStorage() {
8
+ if (_storageReady) {
9
+ return;
118
10
  }
119
- return async (...args) => {
120
- const shouldBypassCache = await opts.shouldBypassCache?.(...args);
121
- if (shouldBypassCache) {
122
- return fn(...args);
123
- }
124
- const key = await (opts.getKey || getKey)(...args);
125
- const shouldInvalidateCache = await opts.shouldInvalidateCache?.(...args);
126
- const entry = await get(key, () => fn(...args), shouldInvalidateCache, args[0] && isHTTPEvent(args[0]) ? args[0] : undefined);
127
- let value = entry.value;
128
- if (opts.transform) {
129
- value = await opts.transform(entry, ...args) || value;
130
- }
131
- return value;
132
- };
133
- }
134
- export function cachedFunction(fn, opts = {}) {
135
- return defineCachedFunction(fn, opts);
11
+ _storageReady = true;
12
+ const storage = useStorage();
13
+ setStorage({
14
+ get: (key) => storage.getItem(key),
15
+ set: (key, value, opts) => storage.setItem(key, value, opts?.ttl ? { ttl: opts.ttl } : undefined)
16
+ });
136
17
  }
137
- function getKey(...args) {
138
- return args.length > 0 ? hash(args) : "";
18
+ function defaultOnError(error) {
19
+ console.error("[cache]", error);
20
+ useNitroApp().captureError?.(error, { tags: ["cache"] });
139
21
  }
140
- function escapeKey(key) {
141
- return String(key).replace(/\W/g, "");
22
+ export function defineCachedFunction(fn, opts = {}) {
23
+ ensureStorage();
24
+ return _defineCachedFunction(fn, {
25
+ group: "nitro/functions",
26
+ onError: defaultOnError,
27
+ ...opts
28
+ });
142
29
  }
143
- export function defineCachedHandler(handler, opts = defaultCacheOptions()) {
144
- const variableHeaderNames = (opts.varies || []).filter(Boolean).map((h) => h.toLowerCase()).sort();
145
- const _opts = {
146
- ...opts,
147
- shouldBypassCache: (event) => {
148
- return event.req.method !== "GET" && event.req.method !== "HEAD";
149
- },
150
- getKey: async (event) => {
151
- // Custom user-defined key
152
- const customKey = await opts.getKey?.(event);
153
- if (customKey) {
154
- return escapeKey(customKey);
155
- }
156
- // Auto-generated key
157
- const _path = event.url.pathname + event.url.search;
158
- let _pathname;
159
- try {
160
- _pathname = escapeKey(decodeURI(parseURL(_path).pathname)).slice(0, 16) || "index";
161
- } catch {
162
- _pathname = "-";
163
- }
164
- const _hashedPath = `${_pathname}.${hash(_path)}`;
165
- const _headers = variableHeaderNames.map((header) => [header, event.req.headers.get(header)]).map(([name, value]) => `${escapeKey(name)}.${hash(value)}`);
166
- return [_hashedPath, ..._headers].join(":");
167
- },
168
- validate: (entry) => {
169
- if (!entry.value) {
170
- return false;
171
- }
172
- if (entry.value.status >= 400) {
173
- return false;
174
- }
175
- if (entry.value.body === undefined) {
176
- return false;
177
- }
178
- // https://github.com/nitrojs/nitro/pull/1857
179
- if (entry.value.headers.etag === "undefined" || entry.value.headers["last-modified"] === "undefined") {
180
- return false;
181
- }
182
- return true;
183
- },
184
- group: opts.group || "nitro/handlers",
185
- integrity: opts.integrity || hash([handler, opts])
186
- };
187
- const _cachedHandler = cachedFunction(async (event) => {
188
- // Filter non variable headers
189
- const filteredHeaders = [...event.req.headers.entries()].filter(([key]) => !variableHeaderNames.includes(key.toLowerCase()));
190
- try {
191
- const originalReq = event.req;
192
- // @ts-expect-error assigning to publicly readonly property
193
- event.req = new Request(event.req.url, {
194
- method: event.req.method,
195
- headers: filteredHeaders
196
- });
197
- // Inherit srvx context
198
- event.req.runtime = originalReq.runtime;
199
- event.req.waitUntil = originalReq.waitUntil;
200
- } catch (error) {
201
- console.error("[cache] Failed to filter headers:", error);
202
- }
203
- // Call handler
204
- const rawValue = await handler(event);
205
- const res = await toResponse(rawValue, event);
206
- // Stringified body
207
- // TODO: support binary responses
208
- const body = await res.text();
209
- if (!res.headers.has("etag")) {
210
- res.headers.set("etag", `W/"${hash(body)}"`);
211
- }
212
- if (!res.headers.has("last-modified")) {
213
- res.headers.set("last-modified", new Date().toUTCString());
214
- }
215
- const cacheControl = [];
216
- if (opts.swr) {
217
- if (opts.maxAge) {
218
- cacheControl.push(`s-maxage=${opts.maxAge}`);
219
- }
220
- if (opts.staleMaxAge) {
221
- cacheControl.push(`stale-while-revalidate=${opts.staleMaxAge}`);
222
- } else {
223
- cacheControl.push("stale-while-revalidate");
224
- }
225
- } else if (opts.maxAge) {
226
- cacheControl.push(`max-age=${opts.maxAge}`);
227
- }
228
- if (cacheControl.length > 0) {
229
- res.headers.set("cache-control", cacheControl.join(", "));
230
- }
231
- const cacheEntry = {
232
- status: res.status,
233
- statusText: res.statusText,
234
- headers: Object.fromEntries(res.headers.entries()),
235
- body
236
- };
237
- return cacheEntry;
238
- }, _opts);
239
- return defineHandler(async (event) => {
240
- // Headers-only mode
241
- if (opts.headersOnly) {
242
- // TODO: Send SWR too
243
- if (handleCacheHeaders(event, { maxAge: opts.maxAge })) {
244
- return;
245
- }
246
- return handler(event);
247
- }
248
- // Call with cache
249
- const response = await _cachedHandler(event);
250
- // Check for cache headers
251
- if (handleCacheHeaders(event, {
252
- modifiedTime: new Date(response.headers["last-modified"]),
253
- etag: response.headers.etag,
254
- maxAge: opts.maxAge
255
- })) {
256
- return;
257
- }
258
- // Send Response
259
- return new FastResponse(response.body, {
260
- status: response.status,
261
- statusText: response.statusText,
262
- headers: response.headers
263
- });
30
+ export function defineCachedHandler(handler, opts = {}) {
31
+ ensureStorage();
32
+ const ocacheHandler = _defineCachedHandler(handler, {
33
+ group: "nitro/handlers",
34
+ onError: defaultOnError,
35
+ toResponse: (value, event) => toResponse(value, event),
36
+ createResponse: (body, init) => new FastResponse(body, init),
37
+ handleCacheHeaders: (event, conditions) => handleCacheHeaders(event, conditions),
38
+ ...opts
264
39
  });
40
+ return defineHandler((event) => ocacheHandler(event));
265
41
  }
@@ -1,5 +1,7 @@
1
+ import type { NitroAsyncContext } from "nitro/types";
1
2
  import type { ServerRequest } from "srvx";
2
- export declare const nitroAsyncContext: unknown;
3
+ import { type UseContext } from "unctx";
4
+ export declare const nitroAsyncContext: UseContext<NitroAsyncContext>;
3
5
  /**
4
6
  *
5
7
  * Access to the current Nitro request.
@@ -5,15 +5,7 @@ export const nitroAsyncContext = /* @__PURE__ */ (() => getContext("nitro-app",
5
5
  asyncContext: import.meta._asyncContext,
6
6
  AsyncLocalStorage: import.meta._asyncContext ? AsyncLocalStorage : undefined
7
7
  }))();
8
- /**
9
- *
10
- * Access to the current Nitro request.
11
- *
12
- * @experimental
13
- * - Requires `experimental.asyncContext: true` config to work.
14
- * - Works in Node.js and limited runtimes only
15
- *
16
- */
8
+
17
9
  export function useRequest() {
18
10
  try {
19
11
  return nitroAsyncContext.use().request;
@@ -1,9 +1,10 @@
1
- import type { HTTPError, HTTPEvent } from "h3";
1
+ import { HTTPError, type HTTPEvent } from "h3";
2
2
  import type { InternalHandlerResponse } from "./utils.mjs";
3
- declare const _default;
4
- export default _default;
3
+ import type { NitroErrorHandler } from "nitro/types";
4
+ declare const errorHandler: NitroErrorHandler;
5
+ export default errorHandler;
5
6
  export declare function defaultHandler(error: HTTPError, event: HTTPEvent, opts?: {
6
7
  silent?: boolean;
7
8
  json?: boolean;
8
9
  }): Promise<InternalHandlerResponse>;
9
- export declare function loadStackTrace(error: any);
10
+ export declare function loadStackTrace(error: any): Promise<void>;
@@ -1,87 +1,84 @@
1
+ import { HTTPError } from "h3";
1
2
  import { getRequestURL } from "h3";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { resolve, dirname } from "node:path";
4
5
  import consola from "consola";
5
- import { ErrorParser } from "youch-core";
6
- import { Youch } from "youch";
7
- import { SourceMapConsumer } from "source-map";
8
6
  import { defineNitroErrorHandler } from "./utils.mjs";
9
7
  import { FastResponse } from "srvx";
10
- export default defineNitroErrorHandler(async function defaultNitroErrorHandler(error, event) {
8
+ const errorHandler = defineNitroErrorHandler(async function defaultNitroErrorHandler(error, event) {
11
9
  const res = await defaultHandler(error, event);
12
10
  return new FastResponse(typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2), res);
13
11
  });
12
+ export default errorHandler;
14
13
  export async function defaultHandler(error, event, opts) {
15
- const isSensitive = error.unhandled;
16
- const status = error.status || 500;
17
- // prettier-ignore
14
+ const unhandled = error.unhandled ?? !HTTPError.isError(error);
15
+ const { status = 500, statusText = "" } = unhandled ? {} : error;
18
16
  const url = getRequestURL(event, {
19
17
  xForwardedHost: true,
20
18
  xForwardedProto: true
21
19
  });
22
- // Redirects with base URL
20
+
23
21
  if (status === 404) {
24
22
  const baseURL = import.meta.baseURL || "/";
25
23
  if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
26
- const redirectTo = `${baseURL}${url.pathname.slice(1)}${url.search}`;
27
24
  return {
28
25
  status: 302,
29
26
  statusText: "Found",
30
- headers: { location: redirectTo },
27
+ headers: new Headers({ location: `${baseURL}${url.pathname.slice(1)}${url.search}` }),
31
28
  body: `Redirecting...`
32
29
  };
33
30
  }
34
31
  }
35
- // Load stack trace with source maps
32
+
36
33
  await loadStackTrace(error).catch(consola.error);
37
- // https://github.com/poppinss/youch
34
+ const { Youch } = await import("youch");
35
+
38
36
  const youch = new Youch();
39
- // Console output
40
- if (isSensitive && !opts?.silent) {
41
- // prettier-ignore
42
- const tags = [error.unhandled && "[unhandled]"].filter(Boolean).join(" ");
43
- const ansiError = await (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
44
- consola.error(`[request error] ${tags} [${event.req.method}] ${url}\n\n`, ansiError);
37
+
38
+ if (unhandled && !opts?.silent) {
39
+ const ansiError = (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
40
+ consola.error(`[request error] [${event.req.method}] ${url}\n\n`, ansiError);
45
41
  }
46
- // Use HTML response only when user-agent expects it (browsers)
42
+
47
43
  const useJSON = opts?.json ?? !event.req.headers.get("accept")?.includes("text/html");
48
- // Prepare headers
49
- const headers = {
50
- "content-type": useJSON ? "application/json" : "text/html",
51
- "x-content-type-options": "nosniff",
52
- "x-frame-options": "DENY",
53
- "referrer-policy": "no-referrer",
54
- "content-security-policy": "script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';"
55
- };
56
- if (status === 404 || !event.res.headers.has("cache-control")) {
57
- headers["cache-control"] = "no-cache";
44
+ const headers = new Headers(unhandled ? {} : error.headers);
45
+ if (useJSON) {
46
+ headers.set("Content-Type", "application/json; charset=utf-8");
47
+ const jsonBody = typeof error.toJSON === "function" ? error.toJSON() : {
48
+ status,
49
+ statusText,
50
+ message: error.message
51
+ };
52
+ return {
53
+ status,
54
+ statusText,
55
+ headers,
56
+ body: {
57
+ error: true,
58
+ stack: error.stack?.split("\n").map((line) => line.trim()),
59
+ ...jsonBody
60
+ }
61
+ };
58
62
  }
59
- // Prepare body
60
- const body = useJSON ? {
61
- error: true,
62
- url,
63
- status,
64
- statusText: error.statusText,
65
- message: error.message,
66
- data: error.data,
67
- stack: error.stack?.split("\n").map((line) => line.trim())
68
- } : await youch.toHTML(error, { request: {
69
- url: url.href,
70
- method: event.req.method,
71
- headers: Object.fromEntries(event.req.headers.entries())
72
- } });
63
+
64
+ headers.set("Content-Type", "text/html; charset=utf-8");
73
65
  return {
74
66
  status,
75
- statusText: error.statusText,
67
+ statusText: unhandled ? "" : error.statusText,
76
68
  headers,
77
- body
69
+ body: await youch.toHTML(error, { request: {
70
+ url: url.href,
71
+ method: event.req.method,
72
+ headers: Object.fromEntries(event.req.headers.entries())
73
+ } })
78
74
  };
79
75
  }
80
- // ---- Source Map support ----
76
+
81
77
  export async function loadStackTrace(error) {
82
78
  if (!(error instanceof Error)) {
83
79
  return;
84
80
  }
81
+ const { ErrorParser } = await import("youch-core");
85
82
  const parsed = await new ErrorParser().defineSourceLoader(sourceLoader).parse(error);
86
83
  const stack = error.message + "\n" + parsed.frames.map((frame) => fmtFrame(frame)).join("\n");
87
84
  Object.defineProperty(error, "stack", { value: stack });
@@ -94,17 +91,18 @@ async function sourceLoader(frame) {
94
91
  return;
95
92
  }
96
93
  if (frame.type === "app") {
97
- // prettier-ignore
94
+
98
95
  const rawSourceMap = await readFile(`${frame.fileName}.map`, "utf8").catch(() => {});
99
96
  if (rawSourceMap) {
97
+ const { SourceMapConsumer } = await import("source-map");
100
98
  const consumer = await new SourceMapConsumer(rawSourceMap);
101
- // prettier-ignore
99
+
102
100
  const originalPosition = consumer.originalPositionFor({
103
101
  line: frame.lineNumber,
104
102
  column: frame.columnNumber
105
103
  });
106
104
  if (originalPosition.source && originalPosition.line) {
107
- // prettier-ignore
105
+
108
106
  frame.fileName = resolve(dirname(frame.fileName), originalPosition.source);
109
107
  frame.lineNumber = originalPosition.line;
110
108
  frame.columnNumber = originalPosition.column || 0;
@@ -1 +1 @@
1
- export declare function trapUnhandledErrors();
1
+ export declare function trapUnhandledErrors(): void;
@@ -1,9 +1,6 @@
1
- import type { HTTPError, HTTPEvent } from "h3";
1
+ import { HTTPError, type HTTPEvent } from "h3";
2
2
  import type { InternalHandlerResponse } from "./utils.mjs";
3
3
  import type { NitroErrorHandler } from "nitro/types";
4
4
  declare const errorHandler: NitroErrorHandler;
5
5
  export default errorHandler;
6
- export declare function defaultHandler(error: HTTPError, event: HTTPEvent, opts?: {
7
- silent?: boolean;
8
- json?: boolean;
9
- }): InternalHandlerResponse;
6
+ export declare function defaultHandler(error: HTTPError, event: HTTPEvent): InternalHandlerResponse;
@@ -1,54 +1,40 @@
1
+ import { HTTPError } from "h3";
1
2
  import { FastResponse } from "srvx";
2
3
  const errorHandler = (error, event) => {
3
4
  const res = defaultHandler(error, event);
4
5
  return new FastResponse(typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2), res);
5
6
  };
6
7
  export default errorHandler;
7
- export function defaultHandler(error, event, opts) {
8
- const isSensitive = error.unhandled;
9
- const status = error.status || 500;
10
- const url = event.url || new URL(event.req.url);
8
+ export function defaultHandler(error, event) {
9
+ const unhandled = error.unhandled ?? !HTTPError.isError(error);
10
+ const { status = 500, statusText = "" } = unhandled ? {} : error;
11
11
  if (status === 404) {
12
+ const url = event.url || new URL(event.req.url);
12
13
  const baseURL = import.meta.baseURL || "/";
13
14
  if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
14
- const redirectTo = `${baseURL}${url.pathname.slice(1)}${url.search}`;
15
15
  return {
16
16
  status: 302,
17
- statusText: "Found",
18
- headers: { location: redirectTo },
19
- body: `Redirecting...`
17
+ headers: new Headers({ location: `${baseURL}${url.pathname.slice(1)}${url.search}` })
20
18
  };
21
19
  }
22
20
  }
23
- // Console output
24
- if (isSensitive && !opts?.silent) {
25
- // prettier-ignore
26
- const tags = [error.unhandled && "[unhandled]"].filter(Boolean).join(" ");
27
- console.error(`[request error] ${tags} [${event.req.method}] ${url}\n`, error);
28
- }
29
- // Send response
30
- const headers = {
31
- "content-type": "application/json",
32
- "x-content-type-options": "nosniff",
33
- "x-frame-options": "DENY",
34
- "referrer-policy": "no-referrer",
35
- "content-security-policy": "script-src 'none'; frame-ancestors 'none';"
36
- };
37
- if (status === 404 || !event.res.headers.has("cache-control")) {
38
- headers["cache-control"] = "no-cache";
39
- }
40
- const body = {
41
- error: true,
42
- url: url.href,
21
+ const headers = new Headers(unhandled ? {} : error.headers);
22
+ headers.set("content-type", "application/json; charset=utf-8");
23
+ const jsonBody = unhandled ? {
43
24
  status,
44
- statusText: error.statusText,
45
- message: isSensitive ? "Server Error" : error.message,
46
- data: isSensitive ? undefined : error.data
25
+ unhandled: true
26
+ } : typeof error.toJSON === "function" ? error.toJSON() : {
27
+ status,
28
+ statusText,
29
+ message: error.message
47
30
  };
48
31
  return {
49
32
  status,
50
- statusText: error.statusText,
33
+ statusText,
51
34
  headers,
52
- body
35
+ body: {
36
+ error: true,
37
+ ...jsonBody
38
+ }
53
39
  };
54
40
  }
@@ -1,8 +1,8 @@
1
1
  import type { NitroErrorHandler } from "nitro/types";
2
2
  export declare function defineNitroErrorHandler(handler: NitroErrorHandler): NitroErrorHandler;
3
3
  export type InternalHandlerResponse = {
4
- status: number;
5
- statusText: string | undefined;
6
- headers: Record<string, string>;
7
- body: string | Record<string, any>;
4
+ status?: number;
5
+ statusText?: string | undefined;
6
+ headers?: HeadersInit;
7
+ body?: string | Record<string, any>;
8
8
  };
@@ -1,2 +1,2 @@
1
1
  import type { NitroRouteMeta } from "nitro/types";
2
- export declare function defineRouteMeta(meta: NitroRouteMeta);
2
+ export declare function defineRouteMeta(meta: NitroRouteMeta): NitroRouteMeta;
@@ -1,3 +1,3 @@
1
1
  import type { NitroAppPlugin } from "nitro/types";
2
- export declare function defineNitroPlugin(def: NitroAppPlugin);
3
- export declare const nitroPlugin: unknown;
2
+ export declare function defineNitroPlugin(def: NitroAppPlugin): NitroAppPlugin;
3
+ export declare const nitroPlugin: (def: NitroAppPlugin) => NitroAppPlugin;
@@ -1,4 +1,11 @@
1
- export declare const headers: unknown;
2
- export declare const redirect: unknown;
3
- export declare const proxy: unknown;
4
- export declare const cache: unknown;
1
+ import type { Middleware } from "h3";
2
+ import type { MatchedRouteRule, NitroRouteRules } from "nitro/types";
3
+ type RouteRuleCtor<T extends keyof NitroRouteRules> = ((m: MatchedRouteRule<T>) => Middleware) & {
4
+ order?: number;
5
+ };
6
+ export declare const headers: RouteRuleCtor<"headers">;
7
+ export declare const redirect: RouteRuleCtor<"redirect">;
8
+ export declare const proxy: RouteRuleCtor<"proxy">;
9
+ export declare const cache: RouteRuleCtor<"cache">;
10
+ export declare const basicAuth: RouteRuleCtor<"auth">;
11
+ export {};