nitropack-nightly 2.10.0-28638494.93d002b7 → 3.0.0-beta-28638629.b32e0831-nitro-nightly-mirror

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 (287) hide show
  1. package/README.md +1 -1
  2. package/cli.d.ts +1 -1
  3. package/config.d.ts +1 -1
  4. package/core.d.ts +1 -1
  5. package/dist/cli/index.d.mts +1 -1
  6. package/dist/cli/index.d.ts +1 -1
  7. package/dist/cli/index.mjs +1 -18
  8. package/dist/config/index.d.mts +1 -6
  9. package/dist/config/index.d.ts +1 -6
  10. package/dist/config/index.mjs +1 -5
  11. package/dist/core/index.d.mts +1 -69
  12. package/dist/core/index.d.ts +1 -69
  13. package/dist/core/index.mjs +1 -2435
  14. package/dist/kit/index.d.mts +1 -44
  15. package/dist/kit/index.d.ts +1 -44
  16. package/dist/kit/index.mjs +1 -71
  17. package/dist/meta/index.d.mts +1 -3
  18. package/dist/meta/index.d.ts +1 -3
  19. package/dist/meta/index.mjs +1 -3
  20. package/dist/presets/index.d.mts +1 -1
  21. package/dist/presets/index.d.ts +1 -2
  22. package/dist/presets/index.mjs +1 -1
  23. package/dist/rollup/index.d.mts +1 -5
  24. package/dist/rollup/index.d.ts +1 -5
  25. package/dist/rollup/index.mjs +1 -2033
  26. package/dist/runtime/index.d.mts +1 -0
  27. package/dist/runtime/index.d.ts +1 -12
  28. package/dist/runtime/index.mjs +1 -17
  29. package/dist/types/index.d.mts +1 -260
  30. package/dist/types/index.d.ts +1 -260
  31. package/dist/types/index.mjs +1 -1
  32. package/kit.d.ts +1 -1
  33. package/meta.d.ts +1 -1
  34. package/package.json +6 -172
  35. package/presets.d.ts +1 -1
  36. package/rollup.d.ts +1 -1
  37. package/runtime-meta.d.ts +1 -4
  38. package/runtime-meta.mjs +1 -30
  39. package/runtime.d.ts +1 -1
  40. package/types.d.ts +1 -1
  41. package/dist/cli/build.mjs +0 -47
  42. package/dist/cli/common.mjs +0 -13
  43. package/dist/cli/dev.mjs +0 -63
  44. package/dist/cli/index2.mjs +0 -14
  45. package/dist/cli/list.mjs +0 -28
  46. package/dist/cli/prepare.mjs +0 -21
  47. package/dist/cli/run.mjs +0 -57
  48. package/dist/presets/_all.gen.d.ts +0 -2
  49. package/dist/presets/_all.gen.mjs +0 -52
  50. package/dist/presets/_nitro/base-worker.d.ts +0 -2
  51. package/dist/presets/_nitro/base-worker.mjs +0 -25
  52. package/dist/presets/_nitro/nitro-dev.d.ts +0 -2
  53. package/dist/presets/_nitro/nitro-dev.mjs +0 -19
  54. package/dist/presets/_nitro/nitro-prerender.d.ts +0 -2
  55. package/dist/presets/_nitro/nitro-prerender.mjs +0 -17
  56. package/dist/presets/_nitro/preset.d.ts +0 -2
  57. package/dist/presets/_nitro/preset.mjs +0 -5
  58. package/dist/presets/_nitro/runtime/nitro-dev.d.ts +0 -1
  59. package/dist/presets/_nitro/runtime/nitro-dev.mjs +0 -86
  60. package/dist/presets/_nitro/runtime/nitro-prerenderer.d.ts +0 -3
  61. package/dist/presets/_nitro/runtime/nitro-prerenderer.mjs +0 -7
  62. package/dist/presets/_nitro/runtime/service-worker.d.ts +0 -1
  63. package/dist/presets/_nitro/runtime/service-worker.mjs +0 -31
  64. package/dist/presets/_nitro/service-worker.d.ts +0 -2
  65. package/dist/presets/_nitro/service-worker.mjs +0 -110
  66. package/dist/presets/_resolve.d.ts +0 -8
  67. package/dist/presets/_resolve.mjs +0 -44
  68. package/dist/presets/_static/preset.d.ts +0 -2
  69. package/dist/presets/_static/preset.mjs +0 -69
  70. package/dist/presets/_types.gen.d.ts +0 -16
  71. package/dist/presets/_types.gen.mjs +0 -0
  72. package/dist/presets/alwaysdata/preset.d.ts +0 -2
  73. package/dist/presets/alwaysdata/preset.mjs +0 -14
  74. package/dist/presets/aws-amplify/preset.d.ts +0 -3
  75. package/dist/presets/aws-amplify/preset.mjs +0 -27
  76. package/dist/presets/aws-amplify/runtime/aws-amplify.d.ts +0 -1
  77. package/dist/presets/aws-amplify/runtime/aws-amplify.mjs +0 -13
  78. package/dist/presets/aws-amplify/types.d.ts +0 -141
  79. package/dist/presets/aws-amplify/types.mjs +0 -0
  80. package/dist/presets/aws-amplify/utils.d.ts +0 -2
  81. package/dist/presets/aws-amplify/utils.mjs +0 -82
  82. package/dist/presets/aws-lambda/preset.d.ts +0 -2
  83. package/dist/presets/aws-lambda/preset.mjs +0 -21
  84. package/dist/presets/aws-lambda/runtime/aws-lambda-streaming.d.ts +0 -15
  85. package/dist/presets/aws-lambda/runtime/aws-lambda-streaming.mjs +0 -53
  86. package/dist/presets/aws-lambda/runtime/aws-lambda.d.ts +0 -4
  87. package/dist/presets/aws-lambda/runtime/aws-lambda.mjs +0 -45
  88. package/dist/presets/azure/preset.d.ts +0 -3
  89. package/dist/presets/azure/preset.mjs +0 -44
  90. package/dist/presets/azure/runtime/azure-functions.d.ts +0 -5
  91. package/dist/presets/azure/runtime/azure-functions.mjs +0 -24
  92. package/dist/presets/azure/runtime/azure-swa.d.ts +0 -5
  93. package/dist/presets/azure/runtime/azure-swa.mjs +0 -30
  94. package/dist/presets/azure/types.d.ts +0 -13
  95. package/dist/presets/azure/types.mjs +0 -0
  96. package/dist/presets/azure/utils.d.ts +0 -3
  97. package/dist/presets/azure/utils.mjs +0 -183
  98. package/dist/presets/bun/preset.d.ts +0 -2
  99. package/dist/presets/bun/preset.mjs +0 -17
  100. package/dist/presets/bun/runtime/bun.d.ts +0 -1
  101. package/dist/presets/bun/runtime/bun.mjs +0 -32
  102. package/dist/presets/cleavr/preset.d.ts +0 -2
  103. package/dist/presets/cleavr/preset.mjs +0 -12
  104. package/dist/presets/cloudflare/preset.d.ts +0 -3
  105. package/dist/presets/cloudflare/preset.mjs +0 -145
  106. package/dist/presets/cloudflare/runtime/cloudflare-module.d.ts +0 -13
  107. package/dist/presets/cloudflare/runtime/cloudflare-module.mjs +0 -102
  108. package/dist/presets/cloudflare/runtime/cloudflare-pages.d.ts +0 -20
  109. package/dist/presets/cloudflare/runtime/cloudflare-pages.mjs +0 -55
  110. package/dist/presets/cloudflare/runtime/cloudflare-worker.d.ts +0 -1
  111. package/dist/presets/cloudflare/runtime/cloudflare-worker.mjs +0 -63
  112. package/dist/presets/cloudflare/types.d.ts +0 -89
  113. package/dist/presets/cloudflare/types.mjs +0 -0
  114. package/dist/presets/cloudflare/types.wrangler.d.ts +0 -974
  115. package/dist/presets/cloudflare/types.wrangler.mjs +0 -0
  116. package/dist/presets/cloudflare/utils.d.ts +0 -3
  117. package/dist/presets/cloudflare/utils.mjs +0 -163
  118. package/dist/presets/deno/preset.d.ts +0 -2
  119. package/dist/presets/deno/preset.mjs +0 -148
  120. package/dist/presets/deno/runtime/_deno-env-polyfill.d.ts +0 -0
  121. package/dist/presets/deno/runtime/_deno-env-polyfill.mjs +0 -1
  122. package/dist/presets/deno/runtime/deno-deploy.d.ts +0 -2
  123. package/dist/presets/deno/runtime/deno-deploy.mjs +0 -32
  124. package/dist/presets/deno/runtime/deno-server.d.ts +0 -4
  125. package/dist/presets/deno/runtime/deno-server.mjs +0 -66
  126. package/dist/presets/digitalocean/preset.d.ts +0 -2
  127. package/dist/presets/digitalocean/preset.mjs +0 -11
  128. package/dist/presets/edgio/preset.d.ts +0 -2
  129. package/dist/presets/edgio/preset.mjs +0 -95
  130. package/dist/presets/firebase/preset.d.ts +0 -3
  131. package/dist/presets/firebase/preset.mjs +0 -51
  132. package/dist/presets/firebase/runtime/firebase-gen-1.d.ts +0 -2
  133. package/dist/presets/firebase/runtime/firebase-gen-1.mjs +0 -8
  134. package/dist/presets/firebase/runtime/firebase-gen-2.d.ts +0 -2
  135. package/dist/presets/firebase/runtime/firebase-gen-2.mjs +0 -15
  136. package/dist/presets/firebase/runtime/firebase-gen-default.d.ts +0 -1
  137. package/dist/presets/firebase/runtime/firebase-gen-default.mjs +0 -1
  138. package/dist/presets/firebase/types.d.ts +0 -37
  139. package/dist/presets/firebase/types.mjs +0 -0
  140. package/dist/presets/firebase/utils.d.ts +0 -3
  141. package/dist/presets/firebase/utils.mjs +0 -50
  142. package/dist/presets/flightcontrol/preset.d.ts +0 -2
  143. package/dist/presets/flightcontrol/preset.mjs +0 -11
  144. package/dist/presets/heroku/preset.d.ts +0 -2
  145. package/dist/presets/heroku/preset.mjs +0 -11
  146. package/dist/presets/iis/preset.d.ts +0 -2
  147. package/dist/presets/iis/preset.mjs +0 -32
  148. package/dist/presets/iis/utils.d.ts +0 -3
  149. package/dist/presets/iis/utils.mjs +0 -159
  150. package/dist/presets/koyeb/preset.d.ts +0 -2
  151. package/dist/presets/koyeb/preset.mjs +0 -11
  152. package/dist/presets/netlify/legacy/preset.d.ts +0 -2
  153. package/dist/presets/netlify/legacy/preset.mjs +0 -142
  154. package/dist/presets/netlify/legacy/runtime/_deno-env-polyfill.d.ts +0 -0
  155. package/dist/presets/netlify/legacy/runtime/_deno-env-polyfill.mjs +0 -1
  156. package/dist/presets/netlify/legacy/runtime/netlify-builder.d.ts +0 -3
  157. package/dist/presets/netlify/legacy/runtime/netlify-builder.mjs +0 -5
  158. package/dist/presets/netlify/legacy/runtime/netlify-edge.d.ts +0 -3
  159. package/dist/presets/netlify/legacy/runtime/netlify-edge.mjs +0 -26
  160. package/dist/presets/netlify/legacy/runtime/netlify-lambda.d.ts +0 -4
  161. package/dist/presets/netlify/legacy/runtime/netlify-lambda.mjs +0 -39
  162. package/dist/presets/netlify/legacy/runtime/netlify.d.ts +0 -4
  163. package/dist/presets/netlify/legacy/runtime/netlify.mjs +0 -22
  164. package/dist/presets/netlify/legacy/utils.d.ts +0 -4
  165. package/dist/presets/netlify/legacy/utils.mjs +0 -113
  166. package/dist/presets/netlify/preset.d.ts +0 -3
  167. package/dist/presets/netlify/preset.mjs +0 -127
  168. package/dist/presets/netlify/runtime/_deno-env-polyfill.d.ts +0 -0
  169. package/dist/presets/netlify/runtime/_deno-env-polyfill.mjs +0 -1
  170. package/dist/presets/netlify/runtime/netlify-edge.d.ts +0 -2
  171. package/dist/presets/netlify/runtime/netlify-edge.mjs +0 -25
  172. package/dist/presets/netlify/runtime/netlify.d.ts +0 -4
  173. package/dist/presets/netlify/runtime/netlify.mjs +0 -54
  174. package/dist/presets/netlify/types.d.ts +0 -12
  175. package/dist/presets/netlify/types.mjs +0 -0
  176. package/dist/presets/netlify/utils.d.ts +0 -5
  177. package/dist/presets/netlify/utils.mjs +0 -94
  178. package/dist/presets/node/preset.d.ts +0 -2
  179. package/dist/presets/node/preset.mjs +0 -49
  180. package/dist/presets/node/runtime/cli.d.ts +0 -1
  181. package/dist/presets/node/runtime/cli.mjs +0 -21
  182. package/dist/presets/node/runtime/cluster.d.ts +0 -1
  183. package/dist/presets/node/runtime/cluster.mjs +0 -60
  184. package/dist/presets/node/runtime/node-listener.d.ts +0 -6
  185. package/dist/presets/node/runtime/node-listener.mjs +0 -15
  186. package/dist/presets/node/runtime/node-server.d.ts +0 -3
  187. package/dist/presets/node/runtime/node-server.mjs +0 -44
  188. package/dist/presets/platform.sh/preset.d.ts +0 -2
  189. package/dist/presets/platform.sh/preset.mjs +0 -11
  190. package/dist/presets/render.com/preset.d.ts +0 -2
  191. package/dist/presets/render.com/preset.mjs +0 -11
  192. package/dist/presets/stormkit/preset.d.ts +0 -2
  193. package/dist/presets/stormkit/preset.mjs +0 -15
  194. package/dist/presets/stormkit/runtime/stormkit.d.ts +0 -21
  195. package/dist/presets/stormkit/runtime/stormkit.mjs +0 -32
  196. package/dist/presets/vercel/preset.d.ts +0 -3
  197. package/dist/presets/vercel/preset.mjs +0 -104
  198. package/dist/presets/vercel/runtime/vercel-edge.d.ts +0 -2
  199. package/dist/presets/vercel/runtime/vercel-edge.mjs +0 -22
  200. package/dist/presets/vercel/runtime/vercel.d.ts +0 -4
  201. package/dist/presets/vercel/runtime/vercel.mjs +0 -17
  202. package/dist/presets/vercel/types.d.ts +0 -78
  203. package/dist/presets/vercel/types.mjs +0 -0
  204. package/dist/presets/vercel/utils.d.ts +0 -5
  205. package/dist/presets/vercel/utils.mjs +0 -186
  206. package/dist/presets/winterjs/preset.d.ts +0 -2
  207. package/dist/presets/winterjs/preset.mjs +0 -20
  208. package/dist/presets/winterjs/runtime/winterjs.d.ts +0 -1
  209. package/dist/presets/winterjs/runtime/winterjs.mjs +0 -69
  210. package/dist/presets/zeabur/preset.d.ts +0 -2
  211. package/dist/presets/zeabur/preset.mjs +0 -70
  212. package/dist/presets/zeabur/runtime/zeabur.d.ts +0 -4
  213. package/dist/presets/zeabur/runtime/zeabur.mjs +0 -8
  214. package/dist/runtime/app.d.ts +0 -2
  215. package/dist/runtime/app.mjs +0 -1
  216. package/dist/runtime/cache.d.ts +0 -1
  217. package/dist/runtime/cache.mjs +0 -6
  218. package/dist/runtime/config.d.ts +0 -1
  219. package/dist/runtime/config.mjs +0 -1
  220. package/dist/runtime/context.d.ts +0 -1
  221. package/dist/runtime/context.mjs +0 -1
  222. package/dist/runtime/database.d.ts +0 -1
  223. package/dist/runtime/database.mjs +0 -1
  224. package/dist/runtime/error.d.ts +0 -1
  225. package/dist/runtime/error.mjs +0 -1
  226. package/dist/runtime/internal/app.d.ts +0 -3
  227. package/dist/runtime/internal/app.mjs +0 -152
  228. package/dist/runtime/internal/cache.d.ts +0 -8
  229. package/dist/runtime/internal/cache.mjs +0 -329
  230. package/dist/runtime/internal/client.d.ts +0 -1
  231. package/dist/runtime/internal/client.mjs +0 -4
  232. package/dist/runtime/internal/config.d.ts +0 -6
  233. package/dist/runtime/internal/config.mjs +0 -58
  234. package/dist/runtime/internal/context.d.ts +0 -12
  235. package/dist/runtime/internal/context.mjs +0 -17
  236. package/dist/runtime/internal/database.d.ts +0 -2
  237. package/dist/runtime/internal/database.mjs +0 -14
  238. package/dist/runtime/internal/debug.d.ts +0 -2
  239. package/dist/runtime/internal/debug.mjs +0 -5
  240. package/dist/runtime/internal/error.d.ts +0 -4
  241. package/dist/runtime/internal/error.mjs +0 -71
  242. package/dist/runtime/internal/index.d.ts +0 -6
  243. package/dist/runtime/internal/index.mjs +0 -16
  244. package/dist/runtime/internal/lib/http-graceful-shutdown.d.ts +0 -16
  245. package/dist/runtime/internal/lib/http-graceful-shutdown.mjs +0 -213
  246. package/dist/runtime/internal/meta.d.ts +0 -2
  247. package/dist/runtime/internal/meta.mjs +0 -3
  248. package/dist/runtime/internal/plugin.d.ts +0 -3
  249. package/dist/runtime/internal/plugin.mjs +0 -4
  250. package/dist/runtime/internal/renderer.d.ts +0 -2
  251. package/dist/runtime/internal/renderer.mjs +0 -38
  252. package/dist/runtime/internal/route-rules.d.ts +0 -14
  253. package/dist/runtime/internal/route-rules.mjs +0 -67
  254. package/dist/runtime/internal/routes/openapi.d.ts +0 -3
  255. package/dist/runtime/internal/routes/openapi.mjs +0 -85
  256. package/dist/runtime/internal/routes/scalar.d.ts +0 -2
  257. package/dist/runtime/internal/routes/scalar.mjs +0 -191
  258. package/dist/runtime/internal/routes/swagger.d.ts +0 -2
  259. package/dist/runtime/internal/routes/swagger.mjs +0 -39
  260. package/dist/runtime/internal/shutdown.d.ts +0 -10
  261. package/dist/runtime/internal/shutdown.mjs +0 -34
  262. package/dist/runtime/internal/static.d.ts +0 -2
  263. package/dist/runtime/internal/static.mjs +0 -89
  264. package/dist/runtime/internal/storage.d.ts +0 -2
  265. package/dist/runtime/internal/storage.mjs +0 -5
  266. package/dist/runtime/internal/task.d.ts +0 -17
  267. package/dist/runtime/internal/task.mjs +0 -73
  268. package/dist/runtime/internal/timing.d.ts +0 -2
  269. package/dist/runtime/internal/timing.mjs +0 -29
  270. package/dist/runtime/internal/utils.azure.d.ts +0 -2
  271. package/dist/runtime/internal/utils.azure.mjs +0 -51
  272. package/dist/runtime/internal/utils.d.ts +0 -23
  273. package/dist/runtime/internal/utils.env.d.ts +0 -7
  274. package/dist/runtime/internal/utils.env.mjs +0 -39
  275. package/dist/runtime/internal/utils.lambda.d.ts +0 -12
  276. package/dist/runtime/internal/utils.lambda.mjs +0 -30
  277. package/dist/runtime/internal/utils.mjs +0 -129
  278. package/dist/runtime/plugin.d.ts +0 -1
  279. package/dist/runtime/plugin.mjs +0 -1
  280. package/dist/runtime/storage.d.ts +0 -1
  281. package/dist/runtime/storage.mjs +0 -1
  282. package/dist/runtime/task.d.ts +0 -1
  283. package/dist/runtime/task.mjs +0 -1
  284. package/dist/runtime/utils.d.ts +0 -1
  285. package/dist/runtime/utils.mjs +0 -1
  286. package/dist/shared/nitro.DkCt8MDS.d.mts +0 -588
  287. package/dist/shared/nitro.DkCt8MDS.d.ts +0 -588
@@ -1,2435 +1 @@
1
- import { createHooks, createDebugger } from 'hookable';
2
- import { createUnimport } from 'unimport';
3
- import consola, { consola as consola$1 } from 'consola';
4
- import { watchConfig, loadConfig } from 'c12';
5
- import { klona } from 'klona/full';
6
- import { resolveCompatibilityDatesFromEnv, formatDate, resolveCompatibilityDates, formatCompatibilityDate } from 'compatx';
7
- import { isDebug, isTest, nodeMajorVersion, provider } from 'std-env';
8
- import { join, resolve, relative, normalize, isAbsolute, dirname } from 'pathe';
9
- import { runtimeDir, pkgDir } from 'nitropack/runtime/meta';
10
- export { runtimeDependencies as nitroRuntimeDependencies } from 'nitropack/runtime/meta';
11
- import { colorize } from 'consola/utils';
12
- import { findWorkspaceDir } from 'pkg-types';
13
- import { resolveNitroPath, isDirectory, writeFile, prettyPath } from 'nitropack/kit';
14
- export { defineNitroPreset } from 'nitropack/kit';
15
- import { existsSync, promises, accessSync } from 'node:fs';
16
- import escapeRE from 'escape-string-regexp';
17
- import { resolveModuleExportNames, resolvePath, parseNodeModulePath, lookupNodeModuleSubpath } from 'mlly';
18
- import defu$1, { defu } from 'defu';
19
- import { withLeadingSlash, withoutTrailingSlash, withTrailingSlash, withBase, parseURL, joinURL, withoutBase } from 'ufo';
20
- import { createStorage as createStorage$1, builtinDrivers } from 'unstorage';
21
- import jiti from 'jiti';
22
- import fsp, { readFile, writeFile as writeFile$1 } from 'node:fs/promises';
23
- import { ofetch } from 'ofetch';
24
- import { globby } from 'globby';
25
- import { pathToFileURL } from 'node:url';
26
- import chalk from 'chalk';
27
- import { toRouteMatcher, createRouter } from 'radix3';
28
- import mime from 'mime';
29
- import { getRollupConfig } from 'nitropack/rollup';
30
- import * as rollup from 'rollup';
31
- import { watch } from 'chokidar';
32
- import { debounce } from 'perfect-debounce';
33
- import { resolveAlias } from 'pathe/utils';
34
- import { genTypeImport } from 'knitwork';
35
- import { generateTypes, resolveSchema } from 'untyped';
36
- import { upperFirst } from 'scule';
37
- import prettyBytes from 'pretty-bytes';
38
- import { gzipSize } from 'gzip-size';
39
- import { version } from 'nitropack/meta';
40
- import zlib from 'node:zlib';
41
- import { Worker } from 'node:worker_threads';
42
- import { eventHandler, getRequestHeader, createError, setResponseHeader, setResponseStatus, getResponseStatus, getResponseStatusText, send, createApp, fromNodeMiddleware, toNodeListener } from 'h3';
43
- import { createProxyServer } from 'httpxy';
44
- import { listen } from 'listhen';
45
- import { servePlaceholder } from 'serve-placeholder';
46
- import serveStatic from 'serve-static';
47
- import fse from 'fs-extra';
48
-
49
- const NitroDefaults = {
50
- // General
51
- debug: isDebug,
52
- timing: isDebug,
53
- logLevel: isTest ? 1 : 3,
54
- runtimeConfig: { app: {}, nitro: {} },
55
- appConfig: {},
56
- appConfigFiles: [],
57
- // Dirs
58
- scanDirs: [],
59
- buildDir: ".nitro",
60
- output: {
61
- dir: "{{ rootDir }}/.output",
62
- serverDir: "{{ output.dir }}/server",
63
- publicDir: "{{ output.dir }}/public"
64
- },
65
- // Features
66
- experimental: {},
67
- future: {},
68
- storage: {},
69
- devStorage: {},
70
- bundledStorage: [],
71
- publicAssets: [],
72
- serverAssets: [],
73
- plugins: [],
74
- tasks: {},
75
- scheduledTasks: {},
76
- imports: {
77
- exclude: [],
78
- dirs: [],
79
- presets: [],
80
- virtualImports: ["#imports"]
81
- },
82
- virtual: {},
83
- compressPublicAssets: false,
84
- ignore: [],
85
- // Dev
86
- dev: false,
87
- devServer: { watch: [] },
88
- watchOptions: { ignoreInitial: true },
89
- devProxy: {},
90
- // Logging
91
- logging: {
92
- compressedSizes: true,
93
- buildSuccess: true
94
- },
95
- // Routing
96
- baseURL: process.env.NITRO_APP_BASE_URL || "/",
97
- handlers: [],
98
- devHandlers: [],
99
- errorHandler: join(runtimeDir, "internal/error"),
100
- routeRules: {},
101
- prerender: {
102
- autoSubfolderIndex: true,
103
- concurrency: 1,
104
- interval: 0,
105
- retry: 3,
106
- retryDelay: 500,
107
- failOnError: false,
108
- crawlLinks: false,
109
- ignore: [],
110
- routes: []
111
- },
112
- // Rollup
113
- unenv: {},
114
- analyze: false,
115
- moduleSideEffects: [
116
- "unenv/runtime/polyfill/",
117
- "node-fetch-native/polyfill",
118
- "node-fetch-native/dist/polyfill",
119
- resolve(runtimeDir, "polyfill/")
120
- ],
121
- replace: {},
122
- node: true,
123
- sourceMap: true,
124
- esbuild: {
125
- options: {
126
- jsxFactory: "h",
127
- jsxFragment: "Fragment"
128
- }
129
- },
130
- // Advanced
131
- typescript: {
132
- strict: false,
133
- generateTsConfig: true,
134
- generateRuntimeConfigTypes: true,
135
- tsconfigPath: "types/tsconfig.json",
136
- internalPaths: false,
137
- tsConfig: {}
138
- },
139
- nodeModulesDirs: [],
140
- hooks: {},
141
- commands: {},
142
- // Framework
143
- framework: {
144
- name: "nitro",
145
- version: ""
146
- }
147
- };
148
-
149
- const fallbackCompatibilityDate = "2024-04-03";
150
- async function resolveCompatibilityOptions(options) {
151
- options.compatibilityDate = resolveCompatibilityDatesFromEnv(
152
- options.compatibilityDate
153
- );
154
- if (!options.compatibilityDate.default && options.preset !== "nitro-prerender") {
155
- options.compatibilityDate.default = await _resolveDefault(options);
156
- }
157
- }
158
- let _fallbackInfoShown = false;
159
- let _promptedUserToUpdate = false;
160
- async function _resolveDefault(options) {
161
- const _todayDate = formatDate(/* @__PURE__ */ new Date());
162
- const consola$1 = consola.withTag("nitro");
163
- consola$1.warn(`No valid compatibility date is specified.`);
164
- const onFallback = () => {
165
- if (!_fallbackInfoShown) {
166
- consola$1.info(
167
- [
168
- `Using \`${fallbackCompatibilityDate}\` as fallback.`,
169
- ` Please specify compatibility date to avoid unwanted behavior changes:`,
170
- ` - Add \`compatibilityDate: '${_todayDate}'\` to the config file.`,
171
- ` - Or set \`COMPATIBILITY_DATE=${_todayDate}\` environment variable.`,
172
- ``
173
- ].join("\n")
174
- );
175
- _fallbackInfoShown = true;
176
- }
177
- return fallbackCompatibilityDate;
178
- };
179
- const shallUpdate = options._cli?.command === "dev" && !_promptedUserToUpdate && await consola$1.prompt(
180
- `Do you want to auto update config file to set ${colorize("cyan", `compatibilityDate: '${_todayDate}'`)}?`,
181
- {
182
- type: "confirm",
183
- default: true
184
- }
185
- );
186
- _promptedUserToUpdate = true;
187
- if (!shallUpdate) {
188
- return onFallback();
189
- }
190
- const { updateConfig } = await import('c12/update');
191
- const updateResult = await updateConfig({
192
- configFile: "nitro.config",
193
- cwd: options.rootDir,
194
- async onCreate({ configFile }) {
195
- const shallCreate = await consola$1.prompt(
196
- `Do you want to initialize a new config in ${colorize("cyan", relative(".", configFile))}?`,
197
- {
198
- type: "confirm",
199
- default: true
200
- }
201
- );
202
- if (shallCreate !== true) {
203
- return false;
204
- }
205
- return _getDefaultNitroConfig();
206
- },
207
- async onUpdate(config) {
208
- config.compatibilityDate = _todayDate;
209
- }
210
- }).catch((error) => {
211
- consola$1.error(`Failed to update config: ${error.message}`);
212
- return null;
213
- });
214
- if (updateResult?.configFile) {
215
- consola$1.success(
216
- `Compatibility date set to \`${_todayDate}\` in \`${relative(".", updateResult.configFile)}\``
217
- );
218
- return _todayDate;
219
- }
220
- return onFallback();
221
- }
222
- function _getDefaultNitroConfig() {
223
- return (
224
- /* js */
225
- `
226
- import { defineNitroConfig } from 'nitropack/config'
227
-
228
- export default defineNitroConfig({})
229
- `
230
- );
231
- }
232
-
233
- async function resolvePathOptions(options) {
234
- options.rootDir = resolve(options.rootDir || ".");
235
- options.workspaceDir = await findWorkspaceDir(options.rootDir).catch(
236
- () => options.rootDir
237
- );
238
- options.srcDir = resolve(options.srcDir || options.rootDir);
239
- for (const key of ["srcDir", "buildDir"]) {
240
- options[key] = resolve(options.rootDir, options[key]);
241
- }
242
- options.alias = {
243
- ...options.alias,
244
- "~/": join(options.srcDir, "/"),
245
- "@/": join(options.srcDir, "/"),
246
- "~~/": join(options.rootDir, "/"),
247
- "@@/": join(options.rootDir, "/")
248
- };
249
- if (!options.static && !options.entry) {
250
- throw new Error(
251
- `Nitro entry is missing! Is "${options.preset}" preset correct?`
252
- );
253
- }
254
- if (options.entry) {
255
- options.entry = resolveNitroPath(options.entry, options);
256
- }
257
- options.output.dir = resolveNitroPath(
258
- options.output.dir || NitroDefaults.output.dir,
259
- options,
260
- options.rootDir
261
- );
262
- options.output.publicDir = resolveNitroPath(
263
- options.output.publicDir || NitroDefaults.output.publicDir,
264
- options,
265
- options.rootDir
266
- );
267
- options.output.serverDir = resolveNitroPath(
268
- options.output.serverDir || NitroDefaults.output.serverDir,
269
- options,
270
- options.rootDir
271
- );
272
- options.nodeModulesDirs.push(resolve(options.workspaceDir, "node_modules"));
273
- options.nodeModulesDirs.push(resolve(options.rootDir, "node_modules"));
274
- options.nodeModulesDirs.push(resolve(pkgDir, "node_modules"));
275
- options.nodeModulesDirs.push(resolve(pkgDir, ".."));
276
- options.nodeModulesDirs = [
277
- ...new Set(
278
- options.nodeModulesDirs.map((dir) => resolve(options.rootDir, dir))
279
- )
280
- ];
281
- options.plugins = options.plugins.map((p) => resolveNitroPath(p, options));
282
- options.scanDirs.unshift(options.srcDir);
283
- options.scanDirs = options.scanDirs.map(
284
- (dir) => resolve(options.srcDir, dir)
285
- );
286
- options.scanDirs = [...new Set(options.scanDirs)];
287
- options.appConfigFiles ??= [];
288
- options.appConfigFiles = options.appConfigFiles.map((file) => _tryResolve(resolveNitroPath(file, options))).filter(Boolean);
289
- for (const dir of options.scanDirs) {
290
- const configFile = _tryResolve("app.config", dir);
291
- if (configFile && !options.appConfigFiles.includes(configFile)) {
292
- options.appConfigFiles.push(configFile);
293
- }
294
- }
295
- }
296
- function _tryResolve(path, base = ".", extensions = ["", ".js", ".ts", ".mjs", ".cjs", ".json"]) {
297
- path = resolve(base, path);
298
- if (existsSync(path)) {
299
- return path;
300
- }
301
- for (const ext of extensions) {
302
- const p = path + ext;
303
- if (existsSync(p)) {
304
- return p;
305
- }
306
- }
307
- }
308
-
309
- async function resolveImportsOptions(options) {
310
- if (options.imports === false) {
311
- return;
312
- }
313
- options.imports.presets ??= [];
314
- options.imports.presets.push(...getNitroImportsPreset());
315
- const h3Exports = await resolveModuleExportNames("h3", {
316
- url: import.meta.url
317
- });
318
- options.imports.presets ??= [];
319
- options.imports.presets.push({
320
- from: "h3",
321
- imports: h3Exports.filter((n) => !/^[A-Z]/.test(n) && n !== "use")
322
- });
323
- options.imports.dirs ??= [];
324
- options.imports.dirs.push(
325
- ...options.scanDirs.map((dir) => join(dir, "utils/*"))
326
- );
327
- if (Array.isArray(options.imports.exclude) && options.imports.exclude.length === 0) {
328
- options.imports.exclude.push(/[/\\]\.git[/\\]/);
329
- options.imports.exclude.push(options.buildDir);
330
- const scanDirsInNodeModules = options.scanDirs.map((dir) => dir.match(/(?<=\/)node_modules\/(.+)$/)?.[1]).filter(Boolean);
331
- options.imports.exclude.push(
332
- scanDirsInNodeModules.length > 0 ? new RegExp(
333
- `node_modules\\/(?!${scanDirsInNodeModules.map((dir) => escapeRE(dir)).join("|")})`
334
- ) : /[/\\]node_modules[/\\]/
335
- );
336
- }
337
- }
338
- function getNitroImportsPreset() {
339
- return [
340
- {
341
- from: "nitropack/runtime",
342
- imports: [
343
- "defineCachedFunction",
344
- "defineCachedEventHandler",
345
- "cachedFunction",
346
- "cachedEventHandler",
347
- "useRuntimeConfig",
348
- "useStorage",
349
- "useNitroApp",
350
- "defineNitroPlugin",
351
- "nitroPlugin",
352
- "defineRenderHandler",
353
- "defineRouteMeta",
354
- "getRouteRules",
355
- "useAppConfig",
356
- "useEvent",
357
- "defineTask",
358
- "runTask",
359
- "defineNitroErrorHandler"
360
- ]
361
- }
362
- ];
363
- }
364
-
365
- async function resolveRouteRulesOptions(options) {
366
- options.routeRules = defu(options.routeRules, options.routes || {});
367
- options.routeRules = normalizeRouteRules(options);
368
- }
369
- function normalizeRouteRules(config) {
370
- const normalizedRules = {};
371
- for (const path in config.routeRules) {
372
- const routeConfig = config.routeRules[path];
373
- const routeRules = {
374
- ...routeConfig,
375
- redirect: void 0,
376
- proxy: void 0
377
- };
378
- if (routeConfig.redirect) {
379
- routeRules.redirect = {
380
- // @ts-ignore
381
- to: "/",
382
- statusCode: 307,
383
- ...typeof routeConfig.redirect === "string" ? { to: routeConfig.redirect } : routeConfig.redirect
384
- };
385
- if (path.endsWith("/**")) {
386
- routeRules.redirect._redirectStripBase = path.slice(0, -3);
387
- }
388
- }
389
- if (routeConfig.proxy) {
390
- routeRules.proxy = typeof routeConfig.proxy === "string" ? { to: routeConfig.proxy } : routeConfig.proxy;
391
- if (path.endsWith("/**")) {
392
- routeRules.proxy._proxyStripBase = path.slice(0, -3);
393
- }
394
- }
395
- if (routeConfig.cors) {
396
- routeRules.headers = {
397
- "access-control-allow-origin": "*",
398
- "access-control-allow-methods": "*",
399
- "access-control-allow-headers": "*",
400
- "access-control-max-age": "0",
401
- ...routeRules.headers
402
- };
403
- }
404
- if (routeConfig.swr) {
405
- routeRules.cache = routeRules.cache || {};
406
- routeRules.cache.swr = true;
407
- if (typeof routeConfig.swr === "number") {
408
- routeRules.cache.maxAge = routeConfig.swr;
409
- }
410
- }
411
- if (routeConfig.cache === false) {
412
- routeRules.cache = false;
413
- }
414
- normalizedRules[path] = routeRules;
415
- }
416
- return normalizedRules;
417
- }
418
-
419
- async function resolveDatabaseOptions(options) {
420
- if (options.experimental.database && options.imports) {
421
- options.imports.presets.push({
422
- from: "nitropack/runtime",
423
- imports: ["useDatabase"]
424
- });
425
- if (options.dev && !options.database && !options.devDatabase) {
426
- options.devDatabase = {
427
- default: {
428
- connector: "sqlite",
429
- options: {
430
- cwd: options.rootDir
431
- }
432
- }
433
- };
434
- } else if (options.node && !options.database) {
435
- options.database = {
436
- default: {
437
- connector: "sqlite",
438
- options: {}
439
- }
440
- };
441
- }
442
- }
443
- }
444
-
445
- async function resolveFetchOptions(options) {
446
- if (options.experimental.nodeFetchCompat === void 0) {
447
- options.experimental.nodeFetchCompat = (nodeMajorVersion || 0) < 18;
448
- if (options.experimental.nodeFetchCompat && provider !== "stackblitz") {
449
- consola.warn(
450
- "Node fetch compatibility is enabled. Please consider upgrading to Node.js >= 18."
451
- );
452
- }
453
- }
454
- if (!options.experimental.nodeFetchCompat) {
455
- options.alias = {
456
- "node-fetch-native/polyfill": "unenv/runtime/mock/empty",
457
- "node-fetch-native": "node-fetch-native/native",
458
- ...options.alias
459
- };
460
- }
461
- }
462
-
463
- async function resolveExportConditionsOptions(options) {
464
- options.exportConditions = _resolveExportConditions(
465
- options.exportConditions,
466
- { dev: options.dev, node: options.node, wasm: options.experimental.wasm }
467
- );
468
- }
469
- function _resolveExportConditions(conditions = [], opts) {
470
- const resolvedConditions = [];
471
- resolvedConditions.push(opts.dev ? "development" : "production");
472
- resolvedConditions.push(...conditions);
473
- if (opts.node) {
474
- resolvedConditions.push("node");
475
- } else {
476
- resolvedConditions.push(
477
- "wintercg",
478
- "worker",
479
- "web",
480
- "browser",
481
- "workerd",
482
- "edge-light",
483
- "netlify",
484
- "edge-routine",
485
- "deno"
486
- );
487
- }
488
- if (opts.wasm) {
489
- resolvedConditions.push("wasm", "unwasm");
490
- }
491
- resolvedConditions.push("import", "default");
492
- return resolvedConditions.filter(
493
- (c, i) => resolvedConditions.indexOf(c) === i
494
- );
495
- }
496
-
497
- async function resolveRuntimeConfigOptions(options) {
498
- options.runtimeConfig = normalizeRuntimeConfig(options);
499
- }
500
- function normalizeRuntimeConfig(config) {
501
- provideFallbackValues(config.runtimeConfig || {});
502
- const runtimeConfig = defu$1(
503
- config.runtimeConfig,
504
- {
505
- app: {
506
- baseURL: config.baseURL
507
- },
508
- nitro: {
509
- envExpansion: config.experimental?.envExpansion,
510
- openAPI: config.openAPI
511
- }
512
- }
513
- );
514
- runtimeConfig.nitro.routeRules = config.routeRules;
515
- return runtimeConfig;
516
- }
517
- function provideFallbackValues(obj) {
518
- for (const key in obj) {
519
- if (obj[key] === void 0 || obj[key] === null) {
520
- obj[key] = "";
521
- } else if (typeof obj[key] === "object") {
522
- provideFallbackValues(obj[key]);
523
- }
524
- }
525
- }
526
-
527
- async function resolveOpenAPIOptions(options) {
528
- if (options.dev && options.experimental.openAPI) {
529
- options.handlers.push({
530
- route: "/_nitro/openapi.json",
531
- handler: join(runtimeDir, "internal/routes/openapi")
532
- });
533
- options.handlers.push({
534
- route: "/_nitro/scalar",
535
- handler: join(runtimeDir, "internal/routes/scalar")
536
- });
537
- options.handlers.push({
538
- route: "/_nitro/swagger",
539
- handler: join(runtimeDir, "internal/routes/swagger")
540
- });
541
- }
542
- }
543
-
544
- async function resolveAssetsOptions(options) {
545
- for (const publicAsset of options.publicAssets) {
546
- publicAsset.dir = resolve(options.srcDir, publicAsset.dir);
547
- publicAsset.baseURL = withLeadingSlash(
548
- withoutTrailingSlash(publicAsset.baseURL || "/")
549
- );
550
- }
551
- for (const dir of options.scanDirs) {
552
- const publicDir = resolve(dir, "public");
553
- if (!existsSync(publicDir)) {
554
- continue;
555
- }
556
- if (options.publicAssets.some((asset) => asset.dir === publicDir)) {
557
- continue;
558
- }
559
- options.publicAssets.push({ dir: publicDir });
560
- }
561
- for (const serverAsset of options.serverAssets) {
562
- serverAsset.dir = resolve(options.srcDir, serverAsset.dir);
563
- }
564
- options.serverAssets.push({
565
- baseName: "server",
566
- dir: resolve(options.srcDir, "assets")
567
- });
568
- for (const asset of options.publicAssets) {
569
- asset.baseURL = asset.baseURL || "/";
570
- const isTopLevel = asset.baseURL === "/";
571
- asset.fallthrough = asset.fallthrough ?? isTopLevel;
572
- const routeRule = options.routeRules[asset.baseURL + "/**"];
573
- asset.maxAge = routeRule?.cache?.maxAge ?? asset.maxAge ?? 0;
574
- if (asset.maxAge && !asset.fallthrough) {
575
- options.routeRules[asset.baseURL + "/**"] = defu(routeRule, {
576
- headers: {
577
- "cache-control": `public, max-age=${asset.maxAge}, immutable`
578
- }
579
- });
580
- }
581
- }
582
- }
583
-
584
- async function resolveURLOptions(options) {
585
- options.baseURL = withLeadingSlash(withTrailingSlash(options.baseURL));
586
- }
587
-
588
- const configResolvers = [
589
- resolveCompatibilityOptions,
590
- resolvePathOptions,
591
- resolveImportsOptions,
592
- resolveRouteRulesOptions,
593
- resolveDatabaseOptions,
594
- resolveFetchOptions,
595
- resolveExportConditionsOptions,
596
- resolveRuntimeConfigOptions,
597
- resolveOpenAPIOptions,
598
- resolveURLOptions,
599
- resolveAssetsOptions
600
- ];
601
- async function loadOptions(configOverrides = {}, opts = {}) {
602
- const options = await _loadUserConfig(configOverrides, opts);
603
- for (const resolver of configResolvers) {
604
- await resolver(options);
605
- }
606
- return options;
607
- }
608
- async function _loadUserConfig(configOverrides = {}, opts = {}) {
609
- let presetOverride = configOverrides.preset || process.env.NITRO_PRESET || process.env.SERVER_PRESET;
610
- if (configOverrides.dev) {
611
- presetOverride = "nitro-dev";
612
- }
613
- configOverrides = klona(configOverrides);
614
- globalThis.defineNitroConfig = globalThis.defineNitroConfig || ((c) => c);
615
- let compatibilityDate = configOverrides.compatibilityDate || opts.compatibilityDate || (process.env.NITRO_COMPATIBILITY_DATE || process.env.SERVER_COMPATIBILITY_DATE || process.env.COMPATIBILITY_DATE);
616
- const { resolvePreset } = await import('nitropack/presets');
617
- const loadedConfig = await (opts.watch ? watchConfig : loadConfig)({
618
- name: "nitro",
619
- cwd: configOverrides.rootDir,
620
- dotenv: configOverrides.dev,
621
- extend: { extendKey: ["extends", "preset"] },
622
- overrides: {
623
- ...configOverrides,
624
- preset: presetOverride
625
- },
626
- async defaultConfig({ configs }) {
627
- if (!compatibilityDate) {
628
- compatibilityDate = configs.main?.compatibilityDate || configs.rc?.compatibilityDate || configs.packageJson?.compatibilityDate;
629
- }
630
- return {
631
- preset: (await resolvePreset("", {
632
- static: configOverrides.static,
633
- compatibilityDate: compatibilityDate || fallbackCompatibilityDate
634
- }))?._meta?.name
635
- };
636
- },
637
- defaults: NitroDefaults,
638
- jitiOptions: {
639
- alias: {
640
- nitropack: "nitropack/config",
641
- "nitropack/config": "nitropack/config"
642
- }
643
- },
644
- async resolve(id) {
645
- const preset = await resolvePreset(id, {
646
- static: configOverrides.static,
647
- compatibilityDate: compatibilityDate || fallbackCompatibilityDate
648
- });
649
- if (preset) {
650
- return {
651
- config: preset
652
- };
653
- }
654
- },
655
- ...opts.c12
656
- });
657
- const options = klona(loadedConfig.config);
658
- options._config = configOverrides;
659
- options._c12 = loadedConfig;
660
- const _presetName = (loadedConfig.layers || []).find((l) => l.config?._meta?.name)?.config?._meta?.name || presetOverride;
661
- options.preset = _presetName;
662
- options.compatibilityDate = resolveCompatibilityDates(
663
- compatibilityDate,
664
- options.compatibilityDate
665
- );
666
- return options;
667
- }
668
-
669
- async function createStorage(nitro) {
670
- const storage = createStorage$1();
671
- const mounts = {
672
- ...nitro.options.storage,
673
- ...nitro.options.devStorage
674
- };
675
- for (const [path, opts] of Object.entries(mounts)) {
676
- if (opts.driver) {
677
- const driver = await import(builtinDrivers[opts.driver] || opts.driver).then((r) => r.default || r);
678
- storage.mount(path, driver(opts));
679
- } else {
680
- nitro.logger.warn(`No \`driver\` set for storage mount point "${path}".`);
681
- }
682
- }
683
- return storage;
684
- }
685
- async function snapshotStorage(nitro) {
686
- const data = {};
687
- const allKeys = [
688
- ...new Set(
689
- await Promise.all(
690
- nitro.options.bundledStorage.map((base) => nitro.storage.getKeys(base))
691
- ).then((r) => r.flat())
692
- )
693
- ];
694
- await Promise.all(
695
- allKeys.map(async (key) => {
696
- data[key] = await nitro.storage.getItem(key);
697
- })
698
- );
699
- return data;
700
- }
701
-
702
- async function installModules(nitro) {
703
- const _modules = [...nitro.options.modules || []];
704
- const modules = await Promise.all(
705
- _modules.map((mod) => _resolveNitroModule(mod, nitro.options))
706
- );
707
- const _installedURLs = /* @__PURE__ */ new Set();
708
- for (const mod of modules) {
709
- if (mod._url) {
710
- if (_installedURLs.has(mod._url)) {
711
- continue;
712
- }
713
- _installedURLs.add(mod._url);
714
- }
715
- await mod.setup(nitro);
716
- }
717
- }
718
- function _resolveNitroModule(mod, nitroOptions) {
719
- let _url;
720
- if (typeof mod === "string") {
721
- globalThis.defineNitroModule = // @ts-ignore
722
- globalThis.defineNitroModule || ((mod2) => mod2);
723
- const _jiti = jiti(nitroOptions.rootDir, {
724
- interopDefault: true,
725
- esmResolve: true,
726
- alias: nitroOptions.alias
727
- });
728
- const _modPath = _jiti.resolve(mod);
729
- _url = _modPath;
730
- mod = _jiti(_modPath);
731
- }
732
- if (typeof mod === "function") {
733
- mod = { setup: mod };
734
- }
735
- if (!mod.setup) {
736
- mod.setup = () => {
737
- };
738
- }
739
- return Promise.resolve({
740
- _url,
741
- ...mod
742
- });
743
- }
744
-
745
- async function updateNitroConfig(nitro, config) {
746
- nitro.options.routeRules = normalizeRouteRules(
747
- config.routeRules ? config : nitro.options
748
- );
749
- nitro.options.runtimeConfig = normalizeRuntimeConfig(
750
- config.runtimeConfig ? config : nitro.options
751
- );
752
- await nitro.hooks.callHook("rollup:reload");
753
- consola.success("Nitro config hot reloaded!");
754
- }
755
-
756
- async function runTask(taskEvent, opts) {
757
- const ctx = await _getTasksContext(opts);
758
- const result = await ctx.devFetch(`/_nitro/tasks/${taskEvent.name}`, {
759
- method: "POST",
760
- body: taskEvent
761
- });
762
- return result;
763
- }
764
- async function listTasks(opts) {
765
- const ctx = await _getTasksContext(opts);
766
- const res = await ctx.devFetch("/_nitro/tasks");
767
- return res.tasks;
768
- }
769
- function addNitroTasksVirtualFile(nitro) {
770
- nitro.options.virtual["#nitro-internal-virtual/tasks"] = () => {
771
- const _scheduledTasks = Object.entries(nitro.options.scheduledTasks || {}).map(([cron, _tasks]) => {
772
- const tasks = (Array.isArray(_tasks) ? _tasks : [_tasks]).filter(
773
- (name) => {
774
- if (!nitro.options.tasks[name]) {
775
- nitro.logger.warn(`Scheduled task \`${name}\` is not defined!`);
776
- return false;
777
- }
778
- return true;
779
- }
780
- );
781
- return { cron, tasks };
782
- }).filter((e) => e.tasks.length > 0);
783
- const scheduledTasks = _scheduledTasks.length > 0 ? _scheduledTasks : false;
784
- return (
785
- /* js */
786
- `
787
- export const scheduledTasks = ${JSON.stringify(scheduledTasks)};
788
-
789
- export const tasks = {
790
- ${Object.entries(nitro.options.tasks).map(
791
- ([name, task]) => `"${name}": {
792
- meta: {
793
- description: ${JSON.stringify(task.description)},
794
- },
795
- resolve: ${task.handler ? `() => import("${normalize(
796
- task.handler
797
- )}").then(r => r.default || r)` : "undefined"},
798
- }`
799
- ).join(",\n")}
800
- };`
801
- );
802
- };
803
- }
804
- const _devHint = `(is dev server running?)`;
805
- async function _getTasksContext(opts) {
806
- const cwd = resolve(process.cwd(), opts?.cwd || ".");
807
- const outDir = resolve(cwd, opts?.buildDir || ".nitro");
808
- const buildInfoPath = resolve(outDir, "nitro.json");
809
- if (!existsSync(buildInfoPath)) {
810
- throw new Error(`Missing info file: \`${buildInfoPath}\` ${_devHint}`);
811
- }
812
- const buildInfo = JSON.parse(
813
- await readFile(buildInfoPath, "utf8")
814
- );
815
- if (!buildInfo.dev?.pid || !buildInfo.dev?.workerAddress) {
816
- throw new Error(
817
- `Missing dev server info in: \`${buildInfoPath}\` ${_devHint}`
818
- );
819
- }
820
- if (!_pidIsRunning(buildInfo.dev.pid)) {
821
- throw new Error(`Dev server is not running (pid: ${buildInfo.dev.pid})`);
822
- }
823
- const devFetch = ofetch.create({
824
- baseURL: `http://${buildInfo.dev.workerAddress.host || "localhost"}:${buildInfo.dev.workerAddress.port || "3000"}`,
825
- // @ts-expect-error
826
- socketPath: buildInfo.dev.workerAddress.socketPath
827
- });
828
- return {
829
- buildInfo,
830
- devFetch
831
- };
832
- }
833
- function _pidIsRunning(pid) {
834
- try {
835
- process.kill(pid, 0);
836
- return true;
837
- } catch {
838
- return false;
839
- }
840
- }
841
-
842
- const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
843
- const suffixRegex = /\.(connect|delete|get|head|options|patch|post|put|trace)(\.(dev|prod|prerender))?$/;
844
- async function scanAndSyncOptions(nitro) {
845
- const scannedPlugins = await scanPlugins(nitro);
846
- for (const plugin of scannedPlugins) {
847
- if (!nitro.options.plugins.includes(plugin)) {
848
- nitro.options.plugins.push(plugin);
849
- }
850
- }
851
- if (nitro.options.experimental.tasks) {
852
- const scannedTasks = await scanTasks(nitro);
853
- for (const scannedTask of scannedTasks) {
854
- if (scannedTask.name in nitro.options.tasks) {
855
- if (!nitro.options.tasks[scannedTask.name].handler) {
856
- nitro.options.tasks[scannedTask.name].handler = scannedTask.handler;
857
- }
858
- } else {
859
- nitro.options.tasks[scannedTask.name] = {
860
- handler: scannedTask.handler,
861
- description: ""
862
- };
863
- }
864
- }
865
- }
866
- const scannedModules = await scanModules(nitro);
867
- nitro.options.modules = nitro.options.modules || [];
868
- for (const modPath of scannedModules) {
869
- if (!nitro.options.modules.includes(modPath)) {
870
- nitro.options.modules.push(modPath);
871
- }
872
- }
873
- }
874
- async function scanHandlers(nitro) {
875
- const middleware = await scanMiddleware(nitro);
876
- const handlers = await Promise.all([
877
- scanServerRoutes(
878
- nitro,
879
- nitro.options.apiDir || "api",
880
- nitro.options.apiBaseURL || "/api"
881
- ),
882
- scanServerRoutes(nitro, nitro.options.routesDir || "routes")
883
- ]).then((r) => r.flat());
884
- nitro.scannedHandlers = [
885
- ...middleware,
886
- ...handlers.filter((h, index, array) => {
887
- return array.findIndex(
888
- (h2) => h.route === h2.route && h.method === h2.method && h.env === h2.env
889
- ) === index;
890
- })
891
- ];
892
- return handlers;
893
- }
894
- async function scanMiddleware(nitro) {
895
- const files = await scanFiles(nitro, "middleware");
896
- return files.map((file) => {
897
- return {
898
- middleware: true,
899
- handler: file.fullPath
900
- };
901
- });
902
- }
903
- async function scanServerRoutes(nitro, dir, prefix = "/") {
904
- const files = await scanFiles(nitro, dir);
905
- return files.map((file) => {
906
- let route = file.path.replace(/\.[A-Za-z]+$/, "").replace(/\[\.{3}]/g, "**").replace(/\[\.{3}(\w+)]/g, "**:$1").replace(/\[(\w+)]/g, ":$1");
907
- route = withLeadingSlash(withoutTrailingSlash(withBase(route, prefix)));
908
- const suffixMatch = route.match(suffixRegex);
909
- let method;
910
- let env;
911
- if (suffixMatch?.index) {
912
- route = route.slice(0, Math.max(0, suffixMatch.index));
913
- method = suffixMatch[1];
914
- env = suffixMatch[3];
915
- }
916
- route = route.replace(/\/index$/, "") || "/";
917
- return {
918
- handler: file.fullPath,
919
- lazy: true,
920
- middleware: false,
921
- route,
922
- method,
923
- env
924
- };
925
- });
926
- }
927
- async function scanPlugins(nitro) {
928
- const files = await scanFiles(nitro, "plugins");
929
- return files.map((f) => f.fullPath);
930
- }
931
- async function scanTasks(nitro) {
932
- const files = await scanFiles(nitro, "tasks");
933
- return files.map((f) => {
934
- const name = f.path.replace(/\/index$/, "").replace(/\.[A-Za-z]+$/, "").replace(/\//g, ":");
935
- return { name, handler: f.fullPath };
936
- });
937
- }
938
- async function scanModules(nitro) {
939
- const files = await scanFiles(nitro, "modules");
940
- return files.map((f) => f.fullPath);
941
- }
942
- async function scanFiles(nitro, name) {
943
- const files = await Promise.all(
944
- nitro.options.scanDirs.map((dir) => scanDir(nitro, dir, name))
945
- ).then((r) => r.flat());
946
- return files;
947
- }
948
- async function scanDir(nitro, dir, name) {
949
- const fileNames = await globby(join(name, GLOB_SCAN_PATTERN), {
950
- cwd: dir,
951
- dot: true,
952
- ignore: nitro.options.ignore,
953
- absolute: true
954
- });
955
- return fileNames.map((fullPath) => {
956
- return {
957
- fullPath,
958
- path: relative(join(dir, name), fullPath)
959
- };
960
- }).sort((a, b) => a.path.localeCompare(b.path));
961
- }
962
-
963
- async function createNitro(config = {}, opts = {}) {
964
- const options = await loadOptions(config, opts);
965
- const nitro = {
966
- options,
967
- hooks: createHooks(),
968
- vfs: {},
969
- logger: consola$1.withTag("nitro"),
970
- scannedHandlers: [],
971
- close: () => nitro.hooks.callHook("close"),
972
- storage: void 0,
973
- async updateConfig(config2) {
974
- updateNitroConfig(nitro, config2);
975
- }
976
- };
977
- await scanAndSyncOptions(nitro);
978
- nitro.storage = await createStorage(nitro);
979
- nitro.hooks.hook("close", async () => {
980
- await nitro.storage.dispose();
981
- });
982
- if (nitro.options.debug) {
983
- createDebugger(nitro.hooks, { tag: "nitro" });
984
- nitro.options.plugins.push(join(runtimeDir, "internal/debug"));
985
- }
986
- if (nitro.options.timing) {
987
- nitro.options.plugins.push(join(runtimeDir, "internal/timing"));
988
- }
989
- if (nitro.options.logLevel !== void 0) {
990
- nitro.logger.level = nitro.options.logLevel;
991
- }
992
- nitro.hooks.addHooks(nitro.options.hooks);
993
- addNitroTasksVirtualFile(nitro);
994
- if (nitro.options.imports) {
995
- nitro.unimport = createUnimport(nitro.options.imports);
996
- await nitro.unimport.init();
997
- nitro.options.virtual["#imports"] = () => nitro.unimport?.toExports() || "";
998
- nitro.options.virtual["#nitro"] = 'export * from "#imports"';
999
- }
1000
- await installModules(nitro);
1001
- return nitro;
1002
- }
1003
-
1004
- async function writeTypes(nitro) {
1005
- const types = {
1006
- routes: {}
1007
- };
1008
- const typesDir = resolve(nitro.options.buildDir, "types");
1009
- const middleware = [...nitro.scannedHandlers, ...nitro.options.handlers];
1010
- for (const mw of middleware) {
1011
- if (typeof mw.handler !== "string" || !mw.route) {
1012
- continue;
1013
- }
1014
- const relativePath = relative(
1015
- typesDir,
1016
- resolveNitroPath(mw.handler, nitro.options)
1017
- ).replace(/\.(js|mjs|cjs|ts|mts|cts|tsx|jsx)$/, "");
1018
- const method = mw.method || "default";
1019
- types.routes[mw.route] ??= {};
1020
- types.routes[mw.route][method] ??= [];
1021
- types.routes[mw.route][method].push(
1022
- `Simplify<Serialize<Awaited<ReturnType<typeof import('${relativePath}').default>>>>`
1023
- );
1024
- }
1025
- let autoImportedTypes = [];
1026
- let autoImportExports = "";
1027
- if (nitro.unimport) {
1028
- await nitro.unimport.init();
1029
- autoImportExports = await nitro.unimport.toExports(typesDir).then(
1030
- (r) => r.replace(/#internal\/nitro/g, relative(typesDir, runtimeDir))
1031
- );
1032
- const resolvedImportPathMap = /* @__PURE__ */ new Map();
1033
- const imports = await nitro.unimport.getImports().then((r) => r.filter((i) => !i.type));
1034
- for (const i of imports) {
1035
- if (resolvedImportPathMap.has(i.from)) {
1036
- continue;
1037
- }
1038
- let path = resolveAlias(i.from, nitro.options.alias);
1039
- if (!isAbsolute(path)) {
1040
- const resolvedPath = await resolvePath(i.from, {
1041
- url: nitro.options.nodeModulesDirs
1042
- }).catch(() => null);
1043
- if (resolvedPath) {
1044
- const { dir, name } = parseNodeModulePath(resolvedPath);
1045
- if (!dir || !name) {
1046
- path = resolvedPath;
1047
- } else {
1048
- const subpath = await lookupNodeModuleSubpath(resolvedPath);
1049
- path = join(dir, name, subpath || "");
1050
- }
1051
- }
1052
- }
1053
- if (existsSync(path) && !await isDirectory(path)) {
1054
- path = path.replace(/\.[a-z]+$/, "");
1055
- }
1056
- if (isAbsolute(path)) {
1057
- path = relative(typesDir, path);
1058
- }
1059
- resolvedImportPathMap.set(i.from, path);
1060
- }
1061
- autoImportedTypes = [
1062
- nitro.options.imports && nitro.options.imports.autoImport !== false ? (await nitro.unimport.generateTypeDeclarations({
1063
- exportHelper: false,
1064
- resolvePath: (i) => resolvedImportPathMap.get(i.from) ?? i.from
1065
- })).trim() : ""
1066
- ];
1067
- }
1068
- await nitro.hooks.callHook("types:extend", types);
1069
- const routes = [
1070
- "// Generated by nitro",
1071
- 'import type { Serialize, Simplify } from "nitropack/types";',
1072
- 'declare module "nitropack/types" {',
1073
- " type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T",
1074
- " interface InternalApi {",
1075
- ...Object.entries(types.routes).map(
1076
- ([path, methods]) => [
1077
- ` '${path}': {`,
1078
- ...Object.entries(methods).map(
1079
- ([method, types2]) => ` '${method}': ${types2.join(" | ")}`
1080
- ),
1081
- " }"
1082
- ].join("\n")
1083
- ),
1084
- " }",
1085
- "}",
1086
- // Makes this a module for augmentation purposes
1087
- "export {}"
1088
- ];
1089
- const config = [
1090
- "// Generated by nitro",
1091
- `
1092
- // App Config
1093
- import type { Defu } from 'defu'
1094
-
1095
- ${nitro.options.appConfigFiles.map(
1096
- (file, index) => genTypeImport(relative(typesDir, file).replace(/\.\w+$/, ""), [
1097
- { name: "default", as: `appConfig${index}` }
1098
- ])
1099
- ).join("\n")}
1100
-
1101
- type UserAppConfig = Defu<{}, [${nitro.options.appConfigFiles.map((_, index) => `typeof appConfig${index}`).join(", ")}]>
1102
-
1103
- declare module "nitropack/types" {
1104
- interface AppConfig extends UserAppConfig {}`,
1105
- nitro.options.typescript.generateRuntimeConfigTypes ? generateTypes(
1106
- await resolveSchema(
1107
- Object.fromEntries(
1108
- Object.entries(nitro.options.runtimeConfig).filter(
1109
- ([key]) => !["app", "nitro"].includes(key)
1110
- )
1111
- )
1112
- ),
1113
- {
1114
- interfaceName: "NitroRuntimeConfig",
1115
- addExport: false,
1116
- addDefaults: false,
1117
- allowExtraKeys: false,
1118
- indentation: 2
1119
- }
1120
- ) : "",
1121
- `}`,
1122
- // Makes this a module for augmentation purposes
1123
- "export {}"
1124
- ];
1125
- const declarations = [
1126
- // local nitropack augmentations
1127
- '/// <reference path="./nitro-routes.d.ts" />',
1128
- '/// <reference path="./nitro-config.d.ts" />',
1129
- // global server auto-imports
1130
- '/// <reference path="./nitro-imports.d.ts" />'
1131
- ];
1132
- const buildFiles = [];
1133
- buildFiles.push({
1134
- path: join(typesDir, "nitro-routes.d.ts"),
1135
- contents: routes.join("\n")
1136
- });
1137
- buildFiles.push({
1138
- path: join(typesDir, "nitro-config.d.ts"),
1139
- contents: config.join("\n")
1140
- });
1141
- buildFiles.push({
1142
- path: join(typesDir, "nitro-imports.d.ts"),
1143
- contents: [...autoImportedTypes, autoImportExports || "export {}"].join(
1144
- "\n"
1145
- )
1146
- });
1147
- buildFiles.push({
1148
- path: join(typesDir, "nitro.d.ts"),
1149
- contents: declarations.join("\n")
1150
- });
1151
- if (nitro.options.typescript.generateTsConfig) {
1152
- const tsConfigPath = resolve(
1153
- nitro.options.buildDir,
1154
- nitro.options.typescript.tsconfigPath
1155
- );
1156
- const tsconfigDir = dirname(tsConfigPath);
1157
- const tsConfig = defu(nitro.options.typescript.tsConfig, {
1158
- compilerOptions: {
1159
- forceConsistentCasingInFileNames: true,
1160
- strict: nitro.options.typescript.strict,
1161
- noEmit: true,
1162
- target: "ESNext",
1163
- module: "ESNext",
1164
- moduleResolution: nitro.options.experimental.typescriptBundlerResolution === false ? "Node" : "Bundler",
1165
- allowJs: true,
1166
- resolveJsonModule: true,
1167
- jsx: "preserve",
1168
- allowSyntheticDefaultImports: true,
1169
- jsxFactory: "h",
1170
- jsxFragmentFactory: "Fragment",
1171
- paths: {
1172
- "#imports": [
1173
- relativeWithDot(tsconfigDir, join(typesDir, "nitro-imports"))
1174
- ],
1175
- "~/*": [
1176
- relativeWithDot(
1177
- tsconfigDir,
1178
- join(nitro.options.alias["~"] || nitro.options.srcDir, "*")
1179
- )
1180
- ],
1181
- "@/*": [
1182
- relativeWithDot(
1183
- tsconfigDir,
1184
- join(nitro.options.alias["@"] || nitro.options.srcDir, "*")
1185
- )
1186
- ],
1187
- "~~/*": [
1188
- relativeWithDot(
1189
- tsconfigDir,
1190
- join(nitro.options.alias["~~"] || nitro.options.rootDir, "*")
1191
- )
1192
- ],
1193
- "@@/*": [
1194
- relativeWithDot(
1195
- tsconfigDir,
1196
- join(nitro.options.alias["@@"] || nitro.options.rootDir, "*")
1197
- )
1198
- ],
1199
- ...nitro.options.typescript.internalPaths ? {
1200
- "nitropack/runtime": [
1201
- relativeWithDot(tsconfigDir, join(runtimeDir, "index"))
1202
- ],
1203
- "#internal/nitro": [
1204
- relativeWithDot(tsconfigDir, join(runtimeDir, "index"))
1205
- ],
1206
- "nitropack/runtime/*": [
1207
- relativeWithDot(tsconfigDir, join(runtimeDir, "*"))
1208
- ],
1209
- "#internal/nitro/*": [
1210
- relativeWithDot(tsconfigDir, join(runtimeDir, "*"))
1211
- ]
1212
- } : {}
1213
- }
1214
- },
1215
- include: [
1216
- relativeWithDot(tsconfigDir, join(typesDir, "nitro.d.ts")).replace(
1217
- /^(?=[^.])/,
1218
- "./"
1219
- ),
1220
- join(relativeWithDot(tsconfigDir, nitro.options.rootDir), "**/*"),
1221
- ...nitro.options.srcDir === nitro.options.rootDir ? [] : [join(relativeWithDot(tsconfigDir, nitro.options.srcDir), "**/*")]
1222
- ]
1223
- });
1224
- for (const alias in tsConfig.compilerOptions.paths) {
1225
- const paths = tsConfig.compilerOptions.paths[alias];
1226
- tsConfig.compilerOptions.paths[alias] = await Promise.all(
1227
- paths.map(async (path) => {
1228
- if (!isAbsolute(path)) {
1229
- return path;
1230
- }
1231
- const stats = await promises.stat(path).catch(
1232
- () => null
1233
- /* file does not exist */
1234
- );
1235
- return relativeWithDot(
1236
- tsconfigDir,
1237
- stats?.isFile() ? path.replace(/(?<=\w)\.\w+$/g, "") : path
1238
- );
1239
- })
1240
- );
1241
- }
1242
- tsConfig.include = [
1243
- ...new Set(
1244
- tsConfig.include.map(
1245
- (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
1246
- )
1247
- )
1248
- ];
1249
- if (tsConfig.exclude) {
1250
- tsConfig.exclude = [
1251
- ...new Set(
1252
- tsConfig.exclude.map(
1253
- (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
1254
- )
1255
- )
1256
- ];
1257
- }
1258
- buildFiles.push({
1259
- path: tsConfigPath,
1260
- contents: JSON.stringify(tsConfig, null, 2)
1261
- });
1262
- }
1263
- await Promise.all(
1264
- buildFiles.map(async (file) => {
1265
- await writeFile(
1266
- resolve(nitro.options.buildDir, file.path),
1267
- file.contents
1268
- );
1269
- })
1270
- );
1271
- }
1272
- const RELATIVE_RE = /^\.{1,2}\//;
1273
- function relativeWithDot(from, to) {
1274
- const rel = relative(from, to);
1275
- return RELATIVE_RE.test(rel) ? rel : "./" + rel;
1276
- }
1277
-
1278
- function formatRollupError(_error) {
1279
- try {
1280
- const logs = [_error.toString()];
1281
- const errors = _error?.errors || [_error];
1282
- for (const error of errors) {
1283
- const id = error.path || error.id || _error.id;
1284
- let path = isAbsolute(id) ? relative(process.cwd(), id) : id;
1285
- const location = error.loc || error.location;
1286
- if (location) {
1287
- path += `:${location.line}:${location.column}`;
1288
- }
1289
- const text = error.text || error.frame;
1290
- logs.push(
1291
- `Rollup error while processing \`${path}\`` + text ? "\n\n" + text : ""
1292
- );
1293
- }
1294
- return logs.join("\n");
1295
- } catch {
1296
- return _error?.toString();
1297
- }
1298
- }
1299
-
1300
- function nitroServerName(nitro) {
1301
- return nitro.options.framework.name === "nitro" ? "Nitro Server" : `${upperFirst(nitro.options.framework.name)} Nitro server`;
1302
- }
1303
-
1304
- async function watchDev(nitro, rollupConfig) {
1305
- let rollupWatcher;
1306
- async function load() {
1307
- if (rollupWatcher) {
1308
- await rollupWatcher.close();
1309
- }
1310
- await scanHandlers(nitro);
1311
- rollupWatcher = startRollupWatcher(nitro, rollupConfig);
1312
- await writeTypes(nitro);
1313
- }
1314
- const reload = debounce(load);
1315
- const watchPatterns = nitro.options.scanDirs.flatMap((dir) => [
1316
- join(dir, nitro.options.apiDir || "api"),
1317
- join(dir, nitro.options.routesDir || "routes"),
1318
- join(dir, "middleware", GLOB_SCAN_PATTERN),
1319
- join(dir, "plugins"),
1320
- join(dir, "modules")
1321
- ]);
1322
- const watchReloadEvents = /* @__PURE__ */ new Set(["add", "addDir", "unlink", "unlinkDir"]);
1323
- const reloadWatcher = watch(watchPatterns, { ignoreInitial: true }).on(
1324
- "all",
1325
- (event) => {
1326
- if (watchReloadEvents.has(event)) {
1327
- reload();
1328
- }
1329
- }
1330
- );
1331
- nitro.hooks.hook("close", () => {
1332
- rollupWatcher.close();
1333
- reloadWatcher.close();
1334
- });
1335
- nitro.hooks.hook("rollup:reload", () => reload());
1336
- await load();
1337
- }
1338
- function startRollupWatcher(nitro, rollupConfig) {
1339
- const watcher = rollup.watch(
1340
- defu$1(rollupConfig, {
1341
- watch: {
1342
- chokidar: nitro.options.watchOptions
1343
- }
1344
- })
1345
- );
1346
- let start;
1347
- watcher.on("event", (event) => {
1348
- switch (event.code) {
1349
- case "START": {
1350
- return;
1351
- }
1352
- case "BUNDLE_START": {
1353
- start = Date.now();
1354
- return;
1355
- }
1356
- case "END": {
1357
- nitro.hooks.callHook("compiled", nitro);
1358
- if (nitro.options.logging.buildSuccess) {
1359
- nitro.logger.success(
1360
- `${nitroServerName(nitro)} built`,
1361
- start ? `in ${Date.now() - start} ms` : ""
1362
- );
1363
- }
1364
- nitro.hooks.callHook("dev:reload");
1365
- return;
1366
- }
1367
- case "ERROR": {
1368
- nitro.logger.error(formatRollupError(event.error));
1369
- }
1370
- }
1371
- });
1372
- return watcher;
1373
- }
1374
-
1375
- async function generateFSTree(dir, options = {}) {
1376
- if (isTest) {
1377
- return;
1378
- }
1379
- const files = await globby("**/*.*", { cwd: dir, ignore: ["*.map"] });
1380
- const items = (await Promise.all(
1381
- files.map(async (file) => {
1382
- const path = resolve(dir, file);
1383
- const src = await promises.readFile(path);
1384
- const size = src.byteLength;
1385
- const gzip = options.compressedSizes ? await gzipSize(src) : 0;
1386
- return { file, path, size, gzip };
1387
- })
1388
- )).sort((a, b) => a.path.localeCompare(b.path));
1389
- let totalSize = 0;
1390
- let totalGzip = 0;
1391
- let totalNodeModulesSize = 0;
1392
- let totalNodeModulesGzip = 0;
1393
- let treeText = "";
1394
- for (const [index, item] of items.entries()) {
1395
- dirname(item.file);
1396
- const rpath = relative(process.cwd(), item.path);
1397
- const treeChar = index === items.length - 1 ? "\u2514\u2500" : "\u251C\u2500";
1398
- const isNodeModules = item.file.includes("node_modules");
1399
- if (isNodeModules) {
1400
- totalNodeModulesSize += item.size;
1401
- totalNodeModulesGzip += item.gzip;
1402
- continue;
1403
- }
1404
- treeText += chalk.gray(
1405
- ` ${treeChar} ${rpath} (${prettyBytes(item.size)})`
1406
- );
1407
- if (options.compressedSizes) {
1408
- treeText += chalk.gray(` (${prettyBytes(item.gzip)} gzip)`);
1409
- }
1410
- treeText += "\n";
1411
- totalSize += item.size;
1412
- totalGzip += item.gzip;
1413
- }
1414
- treeText += `${chalk.cyan("\u03A3 Total size:")} ${prettyBytes(
1415
- totalSize + totalNodeModulesSize
1416
- )}`;
1417
- if (options.compressedSizes) {
1418
- treeText += ` (${prettyBytes(totalGzip + totalNodeModulesGzip)} gzip)`;
1419
- }
1420
- treeText += "\n";
1421
- return treeText;
1422
- }
1423
-
1424
- async function buildProduction(nitro, rollupConfig) {
1425
- await scanHandlers(nitro);
1426
- await writeTypes(nitro);
1427
- await _snapshot(nitro);
1428
- if (!nitro.options.static) {
1429
- nitro.logger.info(
1430
- `Building ${nitroServerName(nitro)} (preset: \`${nitro.options.preset}\`, compatibility date: \`${formatCompatibilityDate(nitro.options.compatibilityDate)}\` )`
1431
- );
1432
- const build = await rollup.rollup(rollupConfig).catch((error) => {
1433
- nitro.logger.error(formatRollupError(error));
1434
- throw error;
1435
- });
1436
- await build.write(rollupConfig.output);
1437
- }
1438
- const buildInfoPath = resolve(nitro.options.output.dir, "nitro.json");
1439
- const buildInfo = {
1440
- date: (/* @__PURE__ */ new Date()).toJSON(),
1441
- preset: nitro.options.preset,
1442
- framework: nitro.options.framework,
1443
- versions: {
1444
- nitro: version
1445
- },
1446
- commands: {
1447
- preview: nitro.options.commands.preview,
1448
- deploy: nitro.options.commands.deploy
1449
- }
1450
- };
1451
- await writeFile(buildInfoPath, JSON.stringify(buildInfo, null, 2));
1452
- if (!nitro.options.static) {
1453
- if (nitro.options.logging.buildSuccess) {
1454
- nitro.logger.success(`${nitroServerName(nitro)} built`);
1455
- }
1456
- if (nitro.options.logLevel > 1) {
1457
- process.stdout.write(
1458
- await generateFSTree(nitro.options.output.serverDir, {
1459
- compressedSizes: nitro.options.logging.compressedSizes
1460
- }) || ""
1461
- );
1462
- }
1463
- }
1464
- await nitro.hooks.callHook("compiled", nitro);
1465
- const rOutput = relative(process.cwd(), nitro.options.output.dir);
1466
- const rewriteRelativePaths = (input) => {
1467
- return input.replace(/([\s:])\.\/(\S*)/g, `$1${rOutput}/$2`);
1468
- };
1469
- if (buildInfo.commands.preview) {
1470
- nitro.logger.success(
1471
- `You can preview this build using \`${rewriteRelativePaths(
1472
- buildInfo.commands.preview
1473
- )}\``
1474
- );
1475
- }
1476
- if (buildInfo.commands.deploy) {
1477
- nitro.logger.success(
1478
- `You can deploy this build using \`${rewriteRelativePaths(
1479
- buildInfo.commands.deploy
1480
- )}\``
1481
- );
1482
- }
1483
- }
1484
- async function _snapshot(nitro) {
1485
- if (nitro.options.bundledStorage.length === 0 || nitro.options.preset === "nitro-prerender") {
1486
- return;
1487
- }
1488
- const storageDir = resolve(nitro.options.buildDir, "snapshot");
1489
- nitro.options.serverAssets.push({
1490
- baseName: "nitro:bundled",
1491
- dir: storageDir
1492
- });
1493
- const data = await snapshotStorage(nitro);
1494
- await Promise.all(
1495
- Object.entries(data).map(async ([path, contents]) => {
1496
- if (typeof contents !== "string") {
1497
- contents = JSON.stringify(contents);
1498
- }
1499
- const fsPath = join(storageDir, path.replace(/:/g, "/"));
1500
- await promises.mkdir(dirname(fsPath), { recursive: true });
1501
- await promises.writeFile(fsPath, contents, "utf8");
1502
- })
1503
- );
1504
- }
1505
-
1506
- async function build(nitro) {
1507
- const rollupConfig = getRollupConfig(nitro);
1508
- await nitro.hooks.callHook("rollup:before", nitro, rollupConfig);
1509
- return nitro.options.dev ? watchDev(nitro, rollupConfig) : buildProduction(nitro, rollupConfig);
1510
- }
1511
-
1512
- async function compressPublicAssets(nitro) {
1513
- const publicFiles = await globby("**", {
1514
- cwd: nitro.options.output.publicDir,
1515
- absolute: false,
1516
- dot: true,
1517
- ignore: ["**/*.gz", "**/*.br"]
1518
- });
1519
- await Promise.all(
1520
- publicFiles.map(async (fileName) => {
1521
- const filePath = resolve(nitro.options.output.publicDir, fileName);
1522
- if (existsSync(filePath + ".gz") || existsSync(filePath + ".br")) {
1523
- return;
1524
- }
1525
- const mimeType = mime.getType(fileName) || "text/plain";
1526
- const fileContents = await fsp.readFile(filePath);
1527
- if (fileContents.length < 1024 || fileName.endsWith(".map") || !isCompressibleMime(mimeType)) {
1528
- return;
1529
- }
1530
- const { gzip, brotli } = nitro.options.compressPublicAssets || {};
1531
- const encodings = [
1532
- gzip !== false && "gzip",
1533
- brotli !== false && "br"
1534
- ].filter(Boolean);
1535
- await Promise.all(
1536
- encodings.map(async (encoding) => {
1537
- const suffix = "." + (encoding === "gzip" ? "gz" : "br");
1538
- const compressedPath = filePath + suffix;
1539
- if (existsSync(compressedPath)) {
1540
- return;
1541
- }
1542
- const gzipOptions = { level: zlib.constants.Z_BEST_COMPRESSION };
1543
- const brotliOptions = {
1544
- [zlib.constants.BROTLI_PARAM_MODE]: isTextMime(mimeType) ? zlib.constants.BROTLI_MODE_TEXT : zlib.constants.BROTLI_MODE_GENERIC,
1545
- [zlib.constants.BROTLI_PARAM_QUALITY]: zlib.constants.BROTLI_MAX_QUALITY,
1546
- [zlib.constants.BROTLI_PARAM_SIZE_HINT]: fileContents.length
1547
- };
1548
- const compressedBuff = await new Promise(
1549
- (resolve2, reject) => {
1550
- const cb = (error, result) => error ? reject(error) : resolve2(result);
1551
- if (encoding === "gzip") {
1552
- zlib.gzip(fileContents, gzipOptions, cb);
1553
- } else {
1554
- zlib.brotliCompress(fileContents, brotliOptions, cb);
1555
- }
1556
- }
1557
- );
1558
- await fsp.writeFile(compressedPath, compressedBuff);
1559
- })
1560
- );
1561
- })
1562
- );
1563
- }
1564
- function isTextMime(mimeType) {
1565
- return /text|javascript|json|xml/.test(mimeType);
1566
- }
1567
- const COMPRESSIBLE_MIMES_RE = /* @__PURE__ */ new Set([
1568
- "application/dash+xml",
1569
- "application/eot",
1570
- "application/font",
1571
- "application/font-sfnt",
1572
- "application/javascript",
1573
- "application/json",
1574
- "application/opentype",
1575
- "application/otf",
1576
- "application/pkcs7-mime",
1577
- "application/protobuf",
1578
- "application/rss+xml",
1579
- "application/truetype",
1580
- "application/ttf",
1581
- "application/vnd.apple.mpegurl",
1582
- "application/vnd.mapbox-vector-tile",
1583
- "application/vnd.ms-fontobject",
1584
- "application/xhtml+xml",
1585
- "application/xml",
1586
- "application/x-font-opentype",
1587
- "application/x-font-truetype",
1588
- "application/x-font-ttf",
1589
- "application/x-httpd-cgi",
1590
- "application/x-javascript",
1591
- "application/x-mpegurl",
1592
- "application/x-opentype",
1593
- "application/x-otf",
1594
- "application/x-perl",
1595
- "application/x-ttf",
1596
- "font/eot",
1597
- "font/opentype",
1598
- "font/otf",
1599
- "font/ttf",
1600
- "image/svg+xml",
1601
- "text/css",
1602
- "text/csv",
1603
- "text/html",
1604
- "text/javascript",
1605
- "text/js",
1606
- "text/plain",
1607
- "text/richtext",
1608
- "text/tab-separated-values",
1609
- "text/xml",
1610
- "text/x-component",
1611
- "text/x-java-source",
1612
- "text/x-script",
1613
- "vnd.apple.mpegurl"
1614
- ]);
1615
- function isCompressibleMime(mimeType) {
1616
- return COMPRESSIBLE_MIMES_RE.has(mimeType);
1617
- }
1618
-
1619
- const allowedExtensions = /* @__PURE__ */ new Set(["", ".json"]);
1620
- const linkParents$1 = /* @__PURE__ */ new Map();
1621
- async function runParallel(inputs, cb, opts) {
1622
- const tasks = /* @__PURE__ */ new Set();
1623
- function queueNext() {
1624
- const route = inputs.values().next().value;
1625
- if (!route) {
1626
- return;
1627
- }
1628
- inputs.delete(route);
1629
- const task = new Promise((resolve) => setTimeout(resolve, opts.interval)).then(() => cb(route)).catch((error) => {
1630
- console.error(error);
1631
- });
1632
- tasks.add(task);
1633
- return task.then(() => {
1634
- tasks.delete(task);
1635
- if (inputs.size > 0) {
1636
- return refillQueue();
1637
- }
1638
- });
1639
- }
1640
- function refillQueue() {
1641
- const workers = Math.min(opts.concurrency - tasks.size, inputs.size);
1642
- return Promise.all(Array.from({ length: workers }, () => queueNext()));
1643
- }
1644
- await refillQueue();
1645
- }
1646
- const LINK_REGEX = /(?<=\s)href=(?!&quot;)["']?([^"'>]+)/g;
1647
- const HTML_ENTITIES = {
1648
- "&lt;": "<",
1649
- "&gt;": ">",
1650
- "&amp;": "&",
1651
- "&apos;": "'",
1652
- "&quot;": '"'
1653
- };
1654
- function escapeHtml(text) {
1655
- return text.replace(
1656
- /&(lt|gt|amp|apos|quot);/g,
1657
- (ch) => HTML_ENTITIES[ch] || ch
1658
- );
1659
- }
1660
- function extractLinks(html, from, res, crawlLinks) {
1661
- const links = [];
1662
- const _links = [];
1663
- if (crawlLinks) {
1664
- _links.push(
1665
- ...[...html.matchAll(LINK_REGEX)].map((m) => escapeHtml(m[1])).filter((m) => !decodeURIComponent(m).startsWith("#")).filter((link) => allowedExtensions.has(getExtension(link)))
1666
- );
1667
- }
1668
- const header = res.headers.get("x-nitro-prerender") || "";
1669
- _links.push(...header.split(",").map((i) => decodeURIComponent(i.trim())));
1670
- for (const link of _links.filter(Boolean)) {
1671
- const _link = parseURL(link);
1672
- if (_link.protocol) {
1673
- continue;
1674
- }
1675
- if (!_link.pathname.startsWith("/")) {
1676
- const fromURL = new URL(from, "http://localhost");
1677
- _link.pathname = new URL(_link.pathname, fromURL).pathname;
1678
- }
1679
- links.push(_link.pathname + _link.search);
1680
- }
1681
- for (const link of links) {
1682
- const _parents = linkParents$1.get(link);
1683
- if (_parents) {
1684
- _parents.add(from);
1685
- } else {
1686
- linkParents$1.set(link, /* @__PURE__ */ new Set([from]));
1687
- }
1688
- }
1689
- return links;
1690
- }
1691
- const EXT_REGEX = /\.[\da-z]+$/;
1692
- function getExtension(link) {
1693
- const pathname = parseURL(link).pathname;
1694
- return (pathname.match(EXT_REGEX) || [])[0] || "";
1695
- }
1696
- function formatPrerenderRoute(route) {
1697
- let str = ` \u251C\u2500 ${route.route} (${route.generateTimeMS}ms)`;
1698
- if (route.error) {
1699
- const parents = linkParents$1.get(route.route);
1700
- const errorColor = chalk[route.error.statusCode === 404 ? "yellow" : "red"];
1701
- const errorLead = parents?.size ? "\u251C\u2500\u2500" : "\u2514\u2500\u2500";
1702
- str += `
1703
- \u2502 ${errorLead} ${errorColor(route.error)}`;
1704
- if (parents?.size) {
1705
- str += `
1706
- ${[...parents.values()].map((link) => ` \u2502 \u2514\u2500\u2500 Linked from ${link}`).join("\n")}`;
1707
- }
1708
- }
1709
- if (route.skip) {
1710
- str += chalk.gray(" (skipped)");
1711
- }
1712
- return chalk.gray(str);
1713
- }
1714
- function matchesIgnorePattern(path, pattern) {
1715
- if (typeof pattern === "string") {
1716
- return path.startsWith(pattern);
1717
- }
1718
- if (typeof pattern === "function") {
1719
- return pattern(path) === true;
1720
- }
1721
- if (pattern instanceof RegExp) {
1722
- return pattern.test(path);
1723
- }
1724
- return false;
1725
- }
1726
-
1727
- const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
1728
- const linkParents = /* @__PURE__ */ new Map();
1729
- async function prerender(nitro) {
1730
- if (nitro.options.noPublicDir) {
1731
- console.warn(
1732
- "[nitro] Skipping prerender since `noPublicDir` option is enabled."
1733
- );
1734
- return;
1735
- }
1736
- const routes = new Set(nitro.options.prerender.routes);
1737
- const prerenderRulePaths = Object.entries(nitro.options.routeRules).filter(([path2, options]) => options.prerender && !path2.includes("*")).map((e) => e[0]);
1738
- for (const route of prerenderRulePaths) {
1739
- routes.add(route);
1740
- }
1741
- await nitro.hooks.callHook("prerender:routes", routes);
1742
- if (routes.size === 0) {
1743
- if (nitro.options.prerender.crawlLinks) {
1744
- routes.add("/");
1745
- } else {
1746
- return;
1747
- }
1748
- }
1749
- nitro.logger.info("Initializing prerenderer");
1750
- nitro._prerenderedRoutes = [];
1751
- nitro._prerenderMeta = nitro._prerenderMeta || {};
1752
- const prerendererConfig = {
1753
- ...nitro.options._config,
1754
- static: false,
1755
- rootDir: nitro.options.rootDir,
1756
- logLevel: 0,
1757
- preset: "nitro-prerender"
1758
- };
1759
- await nitro.hooks.callHook("prerender:config", prerendererConfig);
1760
- const nitroRenderer = await createNitro(prerendererConfig);
1761
- const prerenderStartTime = Date.now();
1762
- await nitro.hooks.callHook("prerender:init", nitroRenderer);
1763
- let path = relative(nitro.options.output.dir, nitro.options.output.publicDir);
1764
- if (!path.startsWith(".")) {
1765
- path = `./${path}`;
1766
- }
1767
- nitroRenderer.options.commands.preview = `npx serve ${path}`;
1768
- nitroRenderer.options.output.dir = nitro.options.output.dir;
1769
- await build(nitroRenderer);
1770
- const serverFilename = typeof nitroRenderer.options.rollupConfig?.output?.entryFileNames === "string" ? nitroRenderer.options.rollupConfig.output.entryFileNames : "index.mjs";
1771
- const serverEntrypoint = resolve(
1772
- nitroRenderer.options.output.serverDir,
1773
- serverFilename
1774
- );
1775
- const { closePrerenderer, localFetch } = await import(pathToFileURL(serverEntrypoint).href);
1776
- const _routeRulesMatcher = toRouteMatcher(
1777
- createRouter({ routes: nitro.options.routeRules })
1778
- );
1779
- const _getRouteRules = (path2) => defu({}, ..._routeRulesMatcher.matchAll(path2).reverse());
1780
- const generatedRoutes = /* @__PURE__ */ new Set();
1781
- const failedRoutes = /* @__PURE__ */ new Set();
1782
- const skippedRoutes = /* @__PURE__ */ new Set();
1783
- const displayedLengthWarns = /* @__PURE__ */ new Set();
1784
- const canPrerender = (route = "/") => {
1785
- if (generatedRoutes.has(route) || skippedRoutes.has(route)) {
1786
- return false;
1787
- }
1788
- for (const pattern of nitro.options.prerender.ignore) {
1789
- if (matchesIgnorePattern(route, pattern)) {
1790
- return false;
1791
- }
1792
- }
1793
- if (_getRouteRules(route).prerender === false) {
1794
- return false;
1795
- }
1796
- return true;
1797
- };
1798
- const canWriteToDisk = (route) => {
1799
- if (route.route.includes("?")) {
1800
- return false;
1801
- }
1802
- const FS_MAX_SEGMENT = 255;
1803
- const FS_MAX_PATH = 1024;
1804
- const FS_MAX_PATH_PUBLIC_HTML = FS_MAX_PATH - (nitro.options.output.publicDir.length + 10);
1805
- if ((route.route.length >= FS_MAX_PATH_PUBLIC_HTML || route.route.split("/").some((s) => s.length > FS_MAX_SEGMENT)) && !displayedLengthWarns.has(route)) {
1806
- displayedLengthWarns.add(route);
1807
- const _route = route.route.slice(0, 60) + "...";
1808
- if (route.route.length >= FS_MAX_PATH_PUBLIC_HTML) {
1809
- nitro.logger.warn(
1810
- `Prerendering long route "${_route}" (${route.route.length}) can cause filesystem issues since it exceeds ${FS_MAX_PATH_PUBLIC_HTML}-character limit when writing to \`${nitro.options.output.publicDir}\`.`
1811
- );
1812
- } else {
1813
- nitro.logger.warn(
1814
- `Skipping prerender of the route "${_route}" since it exceeds the ${FS_MAX_SEGMENT}-character limit in one of the path segments and can cause filesystem issues.`
1815
- );
1816
- return false;
1817
- }
1818
- }
1819
- return true;
1820
- };
1821
- const generateRoute = async (route) => {
1822
- const start = Date.now();
1823
- route = decodeURI(route);
1824
- if (!canPrerender(route)) {
1825
- skippedRoutes.add(route);
1826
- return;
1827
- }
1828
- generatedRoutes.add(route);
1829
- const _route = { route };
1830
- const encodedRoute = encodeURI(route);
1831
- const res = await localFetch(
1832
- withBase(encodedRoute, nitro.options.baseURL),
1833
- {
1834
- headers: { "x-nitro-prerender": encodedRoute },
1835
- retry: nitro.options.prerender.retry,
1836
- retryDelay: nitro.options.prerender.retryDelay
1837
- }
1838
- );
1839
- let dataBuff = Buffer.from(await res.arrayBuffer());
1840
- Object.defineProperty(_route, "contents", {
1841
- get: () => {
1842
- return dataBuff ? dataBuff.toString("utf8") : void 0;
1843
- },
1844
- set(value) {
1845
- if (dataBuff) {
1846
- dataBuff = Buffer.from(value);
1847
- }
1848
- }
1849
- });
1850
- Object.defineProperty(_route, "data", {
1851
- get: () => {
1852
- return dataBuff ? dataBuff.buffer : void 0;
1853
- },
1854
- set(value) {
1855
- if (dataBuff) {
1856
- dataBuff = Buffer.from(value);
1857
- }
1858
- }
1859
- });
1860
- const redirectCodes = [301, 302, 303, 304, 307, 308];
1861
- if (![200, ...redirectCodes].includes(res.status)) {
1862
- _route.error = new Error(`[${res.status}] ${res.statusText}`);
1863
- _route.error.statusCode = res.status;
1864
- _route.error.statusMessage = res.statusText;
1865
- failedRoutes.add(_route);
1866
- }
1867
- _route.generateTimeMS = Date.now() - start;
1868
- const contentType = res.headers.get("content-type") || "";
1869
- const isImplicitHTML = !route.endsWith(".html") && contentType.includes("html") && !JsonSigRx.test(dataBuff.subarray(0, 32).toString("utf8"));
1870
- const routeWithIndex = route.endsWith("/") ? route + "index" : route;
1871
- const htmlPath = route.endsWith("/") || nitro.options.prerender.autoSubfolderIndex ? joinURL(route, "index.html") : route + ".html";
1872
- _route.fileName = withoutBase(
1873
- isImplicitHTML ? htmlPath : routeWithIndex,
1874
- nitro.options.baseURL
1875
- );
1876
- const inferredContentType = mime.getType(_route.fileName) || "text/plain";
1877
- _route.contentType = contentType || inferredContentType;
1878
- await nitro.hooks.callHook("prerender:generate", _route, nitro);
1879
- if (_route.contentType !== inferredContentType) {
1880
- nitro._prerenderMeta[_route.fileName] ||= {};
1881
- nitro._prerenderMeta[_route.fileName].contentType = _route.contentType;
1882
- }
1883
- if (_route.skip || _route.error) {
1884
- await nitro.hooks.callHook("prerender:route", _route);
1885
- nitro.logger.log(formatPrerenderRoute(_route));
1886
- dataBuff = void 0;
1887
- return _route;
1888
- }
1889
- if (canWriteToDisk(_route)) {
1890
- const filePath = join(nitro.options.output.publicDir, _route.fileName);
1891
- await writeFile(filePath, dataBuff);
1892
- nitro._prerenderedRoutes.push(_route);
1893
- } else {
1894
- _route.skip = true;
1895
- }
1896
- if (!_route.error && (isImplicitHTML || route.endsWith(".html"))) {
1897
- const extractedLinks = extractLinks(
1898
- dataBuff.toString("utf8"),
1899
- route,
1900
- res,
1901
- nitro.options.prerender.crawlLinks
1902
- );
1903
- for (const _link of extractedLinks) {
1904
- if (canPrerender(_link)) {
1905
- routes.add(_link);
1906
- }
1907
- }
1908
- }
1909
- await nitro.hooks.callHook("prerender:route", _route);
1910
- nitro.logger.log(formatPrerenderRoute(_route));
1911
- dataBuff = void 0;
1912
- return _route;
1913
- };
1914
- nitro.logger.info(
1915
- nitro.options.prerender.crawlLinks ? `Prerendering ${routes.size} initial routes with crawler` : `Prerendering ${routes.size} routes`
1916
- );
1917
- await runParallel(routes, generateRoute, {
1918
- concurrency: nitro.options.prerender.concurrency,
1919
- interval: nitro.options.prerender.interval
1920
- });
1921
- await closePrerenderer();
1922
- await nitro.hooks.callHook("prerender:done", {
1923
- prerenderedRoutes: nitro._prerenderedRoutes,
1924
- failedRoutes: [...failedRoutes]
1925
- });
1926
- if (nitro.options.prerender.failOnError && failedRoutes.size > 0) {
1927
- nitro.logger.log("\nErrors prerendering:");
1928
- for (const route of failedRoutes) {
1929
- const parents = linkParents.get(route.route);
1930
- parents?.size ? `
1931
- ${[...parents.values()].map((link) => chalk.gray(` \u2502 \u2514\u2500\u2500 Linked from ${link}`)).join("\n")}` : "";
1932
- nitro.logger.log(formatPrerenderRoute(route));
1933
- }
1934
- nitro.logger.log("");
1935
- throw new Error("Exiting due to prerender errors.");
1936
- }
1937
- const prerenderTimeInMs = Date.now() - prerenderStartTime;
1938
- nitro.logger.info(
1939
- `Prerendered ${nitro._prerenderedRoutes.length} routes in ${prerenderTimeInMs / 1e3} seconds`
1940
- );
1941
- if (nitro.options.compressPublicAssets) {
1942
- await compressPublicAssets(nitro);
1943
- }
1944
- }
1945
-
1946
- function createVFSHandler(nitro) {
1947
- return eventHandler(async (event) => {
1948
- const vfsEntries = {
1949
- ...nitro.vfs,
1950
- ...nitro.options.virtual
1951
- };
1952
- const url = event.path || "";
1953
- const isJson = url.endsWith(".json") || getRequestHeader(event, "accept")?.includes("application/json");
1954
- const id = decodeURIComponent(url.replace(/^(\.json)?\/?/, "") || "");
1955
- if (id && !(id in vfsEntries)) {
1956
- throw createError({ message: "File not found", statusCode: 404 });
1957
- }
1958
- let content = id ? vfsEntries[id] : void 0;
1959
- if (typeof content === "function") {
1960
- content = await content();
1961
- }
1962
- if (isJson) {
1963
- return {
1964
- rootDir: nitro.options.rootDir,
1965
- entries: Object.keys(vfsEntries).map((id2) => ({
1966
- id: id2,
1967
- path: "/_vfs.json/" + encodeURIComponent(id2)
1968
- })),
1969
- current: id ? {
1970
- id,
1971
- content
1972
- } : null
1973
- };
1974
- }
1975
- const directories = { [nitro.options.rootDir]: {} };
1976
- const fpaths = Object.keys(vfsEntries);
1977
- for (const item of fpaths) {
1978
- const segments = item.replace(nitro.options.rootDir, "").split("/").filter(Boolean);
1979
- let currentDir = item.startsWith(nitro.options.rootDir) ? directories[nitro.options.rootDir] : directories;
1980
- for (const segment of segments) {
1981
- if (!currentDir[segment]) {
1982
- currentDir[segment] = {};
1983
- }
1984
- currentDir = currentDir[segment];
1985
- }
1986
- }
1987
- const generateHTML = (directory, path = []) => Object.entries(directory).map(([fname, value = {}]) => {
1988
- const subpath = [...path, fname];
1989
- const key = subpath.join("/");
1990
- const encodedUrl = encodeURIComponent(key);
1991
- const linkClass = url === `/${encodedUrl}` ? "bg-gray-700 text-white" : "hover:bg-gray-800 text-gray-200";
1992
- return Object.keys(value).length === 0 ? `
1993
- <li class="flex flex-nowrap">
1994
- <a href="/_vfs/${encodedUrl}" class="w-full text-sm px-2 py-1 border-b border-gray-10 ${linkClass}">
1995
- ${fname}
1996
- </a>
1997
- </li>
1998
- ` : `
1999
- <li>
2000
- <details ${url.startsWith(`/${encodedUrl}`) ? "open" : ""}>
2001
- <summary class="w-full text-sm px-2 py-1 border-b border-gray-10 hover:bg-gray-800 text-gray-200">
2002
- ${fname}
2003
- </summary>
2004
- <ul class="ml-4">
2005
- ${generateHTML(value, subpath)}
2006
- </ul>
2007
- </details>
2008
- </li>
2009
- `;
2010
- }).join("");
2011
- const rootDirectory = directories[nitro.options.rootDir];
2012
- delete directories[nitro.options.rootDir];
2013
- const items = generateHTML(rootDirectory, [nitro.options.rootDir]) + generateHTML(directories);
2014
- const files = `
2015
- <div class="h-full overflow-auto border-r border-gray:10">
2016
- <p class="text-white text-bold text-center py-1 opacity-50">Virtual Files</p>
2017
- <ul class="flex flex-col">${items}</ul>
2018
- </div>
2019
- `;
2020
- const file = id ? editorTemplate({
2021
- readOnly: true,
2022
- language: id.endsWith("html") ? "html" : "javascript",
2023
- theme: "vs-dark",
2024
- value: content,
2025
- wordWrap: "wordWrapColumn",
2026
- wordWrapColumn: 80
2027
- }) : `
2028
- <div class="w-full h-full flex opacity-50">
2029
- <h1 class="text-white m-auto">Select a virtual file to inspect</h1>
2030
- </div>
2031
- `;
2032
- return (
2033
- /* html */
2034
- `
2035
- <!doctype html>
2036
- <html>
2037
- <head>
2038
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@unocss/reset/tailwind.min.css" />
2039
- <link rel="stylesheet" data-name="vs/editor/editor.main" href="${vsUrl}/editor/editor.main.min.css">
2040
- <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime"><\/script>
2041
- <style>
2042
- html {
2043
- background: #1E1E1E;
2044
- color: white;
2045
- }
2046
- [un-cloak] {
2047
- display: none;
2048
- }
2049
- </style>
2050
- </head>
2051
- <body class="bg-[#1E1E1E]">
2052
- <div un-cloak class="h-screen grid grid-cols-[300px_1fr]">
2053
- ${files}
2054
- ${file}
2055
- </div>
2056
- </body>
2057
- </html>`
2058
- );
2059
- });
2060
- }
2061
- const monacoVersion = "0.30.0";
2062
- const monacoUrl = `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/${monacoVersion}/min`;
2063
- const vsUrl = `${monacoUrl}/vs`;
2064
- const editorTemplate = (options) => `
2065
- <div id="editor" class="min-h-screen w-full h-full"></div>
2066
- <script src="${vsUrl}/loader.min.js"><\/script>
2067
- <script>
2068
- require.config({ paths: { vs: '${vsUrl}' } })
2069
-
2070
- const proxy = URL.createObjectURL(new Blob([\`
2071
- self.MonacoEnvironment = { baseUrl: '${monacoUrl}' }
2072
- importScripts('${vsUrl}/base/worker/workerMain.min.js')
2073
- \`], { type: 'text/javascript' }))
2074
- window.MonacoEnvironment = { getWorkerUrl: () => proxy }
2075
-
2076
- setTimeout(() => {
2077
- require(['vs/editor/editor.main'], function () {
2078
- monaco.editor.create(document.getElementById('editor'), ${JSON.stringify(
2079
- options
2080
- )})
2081
- })
2082
- }, 0);
2083
- <\/script>
2084
- `;
2085
-
2086
- function errorHandler(error, event) {
2087
- setResponseHeader(event, "Content-Type", "text/html; charset=UTF-8");
2088
- setResponseStatus(event, 503, "Server Unavailable");
2089
- let body;
2090
- let title;
2091
- if (error) {
2092
- title = `${getResponseStatus(event)} ${getResponseStatusText(event)}`;
2093
- body = `<code><pre>${error.stack}</pre></code>`;
2094
- } else {
2095
- title = "Reloading server...";
2096
- body = "<progress></progress><script>document.querySelector('progress').indeterminate=true<\/script>";
2097
- }
2098
- return send(
2099
- event,
2100
- `<!DOCTYPE html>
2101
- <html lang="en">
2102
- <head>
2103
- <meta charset="utf-8">
2104
- <meta name="viewport" content="width=device-width, initial-scale=1">
2105
- ${error ? "" : '<meta http-equiv="refresh" content="2">'}
2106
- <title>${title}</title>
2107
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico/css/pico.min.css">
2108
- </head>
2109
- <body>
2110
- <main class="container">
2111
- <article>
2112
- <header>
2113
- <h2>${title}</h2>
2114
- </header>
2115
- ${body}
2116
- <footer>
2117
- Check console logs for more information.
2118
- </footer>
2119
- </article>
2120
- </main>
2121
- </body>
2122
- </html>
2123
- `
2124
- );
2125
- }
2126
-
2127
- function initWorker(filename) {
2128
- if (!existsSync(filename)) {
2129
- return;
2130
- }
2131
- return new Promise((resolve2, reject) => {
2132
- const worker = new Worker(filename);
2133
- worker.once("exit", (code) => {
2134
- reject(
2135
- new Error(
2136
- code ? "[worker] exited with code: " + code : "[worker] exited"
2137
- )
2138
- );
2139
- });
2140
- worker.once("error", (err) => {
2141
- const newErr = new Error("[worker init] " + err.message);
2142
- newErr.stack = err.stack;
2143
- reject(newErr);
2144
- });
2145
- const addressListener = (event) => {
2146
- if (!event || !event?.address) {
2147
- return;
2148
- }
2149
- worker.off("message", addressListener);
2150
- resolve2({
2151
- worker,
2152
- address: event.address
2153
- });
2154
- };
2155
- worker.on("message", addressListener);
2156
- });
2157
- }
2158
- async function killWorker(worker, nitro) {
2159
- if (!worker) {
2160
- return;
2161
- }
2162
- if (worker.worker) {
2163
- worker.worker.postMessage({ event: "shutdown" });
2164
- const gracefulShutdownTimeout = Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10) || 3;
2165
- await new Promise((resolve2) => {
2166
- const timeout = setTimeout(() => {
2167
- nitro.logger.warn(
2168
- `[nitro] [dev] Force closing worker after ${gracefulShutdownTimeout} seconds...`
2169
- );
2170
- resolve2();
2171
- }, gracefulShutdownTimeout * 1e3);
2172
- worker.worker?.once("message", (message) => {
2173
- if (message.event === "exit") {
2174
- clearTimeout(timeout);
2175
- resolve2();
2176
- }
2177
- });
2178
- });
2179
- worker.worker.removeAllListeners();
2180
- await worker.worker.terminate();
2181
- worker.worker = null;
2182
- }
2183
- if (worker.address.socketPath && existsSync(worker.address.socketPath)) {
2184
- await promises.rm(worker.address.socketPath).catch(() => {
2185
- });
2186
- }
2187
- }
2188
- function createDevServer(nitro) {
2189
- const workerEntry = resolve(
2190
- nitro.options.output.dir,
2191
- nitro.options.output.serverDir,
2192
- "index.mjs"
2193
- );
2194
- const errorHandler$1 = nitro.options.devErrorHandler || errorHandler;
2195
- let lastError;
2196
- let reloadPromise;
2197
- let currentWorker;
2198
- async function _reload() {
2199
- const oldWorker = currentWorker;
2200
- currentWorker = void 0;
2201
- await killWorker(oldWorker, nitro);
2202
- currentWorker = await initWorker(workerEntry);
2203
- if (!currentWorker) {
2204
- return;
2205
- }
2206
- const buildInfoPath = resolve(nitro.options.buildDir, "nitro.json");
2207
- const buildInfo = {
2208
- date: (/* @__PURE__ */ new Date()).toJSON(),
2209
- preset: nitro.options.preset,
2210
- framework: nitro.options.framework,
2211
- versions: {
2212
- nitro: version
2213
- },
2214
- dev: {
2215
- pid: process.pid,
2216
- workerAddress: currentWorker?.address
2217
- }
2218
- };
2219
- await writeFile$1(buildInfoPath, JSON.stringify(buildInfo, null, 2));
2220
- }
2221
- const reload = debounce(() => {
2222
- reloadPromise = _reload().then(() => {
2223
- lastError = void 0;
2224
- }).catch((error) => {
2225
- console.error("[worker reload]", error);
2226
- lastError = error;
2227
- }).finally(() => {
2228
- reloadPromise = void 0;
2229
- });
2230
- return reloadPromise;
2231
- });
2232
- nitro.hooks.hook("dev:reload", reload);
2233
- const app = createApp();
2234
- for (const handler of nitro.options.devHandlers) {
2235
- app.use(handler.route || "/", handler.handler);
2236
- }
2237
- app.use("/_vfs", createVFSHandler(nitro));
2238
- for (const asset of nitro.options.publicAssets) {
2239
- const url = joinURL(
2240
- nitro.options.runtimeConfig.app.baseURL,
2241
- asset.baseURL || "/"
2242
- );
2243
- app.use(url, fromNodeMiddleware(serveStatic(asset.dir)));
2244
- if (!asset.fallthrough) {
2245
- app.use(url, fromNodeMiddleware(servePlaceholder()));
2246
- }
2247
- }
2248
- for (const route of Object.keys(nitro.options.devProxy).sort().reverse()) {
2249
- let opts = nitro.options.devProxy[route];
2250
- if (typeof opts === "string") {
2251
- opts = { target: opts };
2252
- }
2253
- const proxy2 = createProxy(opts);
2254
- app.use(
2255
- route,
2256
- eventHandler(async (event) => {
2257
- await proxy2.handle(event);
2258
- })
2259
- );
2260
- }
2261
- const proxy = createProxy();
2262
- proxy.proxy.on("proxyReq", (proxyReq, req) => {
2263
- if (!proxyReq.hasHeader("x-forwarded-for")) {
2264
- const address = req.socket.remoteAddress;
2265
- if (address) {
2266
- proxyReq.appendHeader("x-forwarded-for", address);
2267
- }
2268
- }
2269
- if (!proxyReq.hasHeader("x-forwarded-port")) {
2270
- const localPort = req?.socket?.localPort;
2271
- if (localPort) {
2272
- proxyReq.setHeader("x-forwarded-port", req.socket.localPort);
2273
- }
2274
- }
2275
- if (!proxyReq.hasHeader("x-forwarded-Proto")) {
2276
- const encrypted = req?.connection?.encrypted;
2277
- proxyReq.setHeader("x-forwarded-proto", encrypted ? "https" : "http");
2278
- }
2279
- });
2280
- const getWorkerAddress = () => {
2281
- const address = currentWorker?.address;
2282
- if (!address) {
2283
- return;
2284
- }
2285
- if (address.socketPath) {
2286
- try {
2287
- accessSync(address.socketPath);
2288
- } catch (error) {
2289
- if (!lastError) {
2290
- lastError = error;
2291
- }
2292
- return;
2293
- }
2294
- }
2295
- return address;
2296
- };
2297
- app.use(
2298
- eventHandler(async (event) => {
2299
- await reloadPromise;
2300
- const address = getWorkerAddress();
2301
- if (!address) {
2302
- const error = lastError || createError("Worker not ready");
2303
- return errorHandler$1(error, event);
2304
- }
2305
- await proxy.handle(event, { target: address }).catch((error) => {
2306
- lastError = error;
2307
- throw error;
2308
- });
2309
- })
2310
- );
2311
- const upgrade = (req, socket, head) => {
2312
- return proxy.proxy.ws(
2313
- req,
2314
- // @ts-expect-error
2315
- socket,
2316
- {
2317
- target: getWorkerAddress(),
2318
- xfwd: true
2319
- },
2320
- head
2321
- );
2322
- };
2323
- let listeners = [];
2324
- const _listen = async (port, opts) => {
2325
- const listener = await listen(toNodeListener(app), { port, ...opts });
2326
- listener.server.on("upgrade", (req, sock, head) => {
2327
- upgrade(req, sock, head);
2328
- });
2329
- listeners.push(listener);
2330
- return listener;
2331
- };
2332
- let watcher;
2333
- if (nitro.options.devServer.watch.length > 0) {
2334
- watcher = watch(nitro.options.devServer.watch, nitro.options.watchOptions);
2335
- watcher.on("add", reload).on("change", reload);
2336
- }
2337
- async function close() {
2338
- if (watcher) {
2339
- await watcher.close();
2340
- }
2341
- await killWorker(currentWorker, nitro);
2342
- await Promise.all(listeners.map((l) => l.close()));
2343
- listeners = [];
2344
- }
2345
- nitro.hooks.hook("close", close);
2346
- return {
2347
- reload,
2348
- listen: _listen,
2349
- app,
2350
- close,
2351
- watcher,
2352
- upgrade
2353
- };
2354
- }
2355
- function createProxy(defaults = {}) {
2356
- const proxy = createProxyServer(defaults);
2357
- const handle = async (event, opts = {}) => {
2358
- try {
2359
- await proxy.web(event.node.req, event.node.res, opts);
2360
- } catch (error) {
2361
- if (error?.code !== "ECONNRESET") {
2362
- throw error;
2363
- }
2364
- }
2365
- };
2366
- return {
2367
- proxy,
2368
- handle
2369
- };
2370
- }
2371
-
2372
- const NEGATION_RE = /^(!?)(.*)$/;
2373
- const PARENT_DIR_GLOB_RE = /!?\.\.\//;
2374
- async function copyPublicAssets(nitro) {
2375
- if (nitro.options.noPublicDir) {
2376
- return;
2377
- }
2378
- for (const asset of nitro.options.publicAssets) {
2379
- const srcDir = asset.dir;
2380
- const dstDir = join(nitro.options.output.publicDir, asset.baseURL);
2381
- if (await isDirectory(srcDir)) {
2382
- const includePatterns = [
2383
- "**",
2384
- ...nitro.options.ignore.map((p) => {
2385
- const [_, negation, pattern] = p.match(NEGATION_RE) || [];
2386
- return (
2387
- // Convert ignore to include patterns
2388
- (negation ? "" : "!") + // Make non-glob patterns relative to publicAssetDir
2389
- (pattern.startsWith("*") ? pattern : relative(srcDir, resolve(nitro.options.srcDir, pattern)))
2390
- );
2391
- })
2392
- ].filter((p) => !PARENT_DIR_GLOB_RE.test(p));
2393
- const publicAssets = await globby(includePatterns, {
2394
- cwd: srcDir,
2395
- absolute: false,
2396
- dot: true
2397
- });
2398
- await Promise.all(
2399
- publicAssets.map(async (file) => {
2400
- const src = join(srcDir, file);
2401
- const dst = join(dstDir, file);
2402
- if (!existsSync(dst)) {
2403
- await promises.cp(src, dst);
2404
- }
2405
- })
2406
- );
2407
- }
2408
- }
2409
- if (nitro.options.compressPublicAssets) {
2410
- await compressPublicAssets(nitro);
2411
- }
2412
- nitro.logger.success(
2413
- "Generated public " + prettyPath(nitro.options.output.publicDir)
2414
- );
2415
- }
2416
-
2417
- async function prepare(nitro) {
2418
- await prepareDir(nitro.options.output.dir);
2419
- if (!nitro.options.noPublicDir) {
2420
- await prepareDir(nitro.options.output.publicDir);
2421
- }
2422
- if (!nitro.options.static) {
2423
- await prepareDir(nitro.options.output.serverDir);
2424
- }
2425
- }
2426
- async function prepareDir(dir) {
2427
- await fsp.mkdir(dir, { recursive: true });
2428
- await fse.emptyDir(dir);
2429
- }
2430
-
2431
- function defineNitroConfig(config) {
2432
- return config;
2433
- }
2434
-
2435
- export { GLOB_SCAN_PATTERN, build, copyPublicAssets, createDevServer, createNitro, defineNitroConfig, listTasks, loadOptions, prepare, prerender, runTask, scanHandlers, scanMiddleware, scanModules, scanPlugins, scanServerRoutes, scanTasks, writeTypes };
1
+ export * from "nitro/core";