nitro-nightly 3.1.0-20251028-090722-437659e4 → 3.1.0-20251028-131831-fe9fd554

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 (157) hide show
  1. package/dist/_build/build.mjs +379 -14
  2. package/dist/_build/{rollup.mjs → build2.mjs} +218 -68
  3. package/dist/_build/info.mjs +963 -7
  4. package/dist/_build/prepare.mjs +1491 -2
  5. package/dist/_build/snapshot.mjs +155 -31
  6. package/dist/_build/vite.mjs +43 -2307
  7. package/dist/_build/vite2.mjs +149 -0
  8. package/dist/{_deps → _chunks/_deps}/c12.mjs +1 -1
  9. package/dist/{_deps → _chunks/_deps}/giget.mjs +1 -1
  10. package/dist/_chunks/_deps/klona.mjs +137 -0
  11. package/dist/{_deps → _chunks/_deps}/knitwork.mjs +1 -1
  12. package/dist/{_deps → _chunks/_deps}/local-pkg.mjs +1 -1
  13. package/dist/{_deps → _chunks/_deps}/mlly.mjs +1 -1
  14. package/dist/{_deps → _chunks/_deps}/nypm.mjs +1 -1
  15. package/dist/{_deps → _chunks/_deps}/pathe.mjs +1 -1
  16. package/dist/{_deps → _chunks/_deps}/pkg-types.mjs +2 -2
  17. package/dist/{_deps → _chunks/_deps}/rou3.mjs +1 -1
  18. package/dist/_chunks/_deps/std-env.mjs +3 -0
  19. package/dist/{_deps → _chunks/_deps}/unimport.mjs +2 -2
  20. package/dist/{_deps → _chunks/_deps}/unplugin-utils.mjs +1 -1
  21. package/dist/{_deps → _chunks/_deps}/untyped.mjs +1 -1
  22. package/dist/{_deps → _chunks/_deps}/unwasm.mjs +2 -2
  23. package/dist/{_presets → _chunks/_presets}/_resolve.mjs +2 -2
  24. package/dist/{_presets → _chunks/_presets}/_utils.mjs +1 -1
  25. package/dist/{_presets → _chunks/_presets}/azure.mjs +1 -1
  26. package/dist/{_presets → _chunks/_presets}/cloudflare.mjs +4 -4
  27. package/dist/{_presets → _chunks/_presets}/deno.mjs +1 -1
  28. package/dist/{_presets → _chunks/_presets}/firebase.mjs +1 -1
  29. package/dist/{_presets → _chunks/_presets}/iis.mjs +1 -1
  30. package/dist/{_presets → _chunks/_presets}/index.mjs +1 -1
  31. package/dist/{_presets → _chunks/_presets}/vercel.mjs +3 -3
  32. package/dist/{_presets → _chunks/_presets}/zeabur.mjs +1 -1
  33. package/dist/_chunks/app.mjs +600 -0
  34. package/dist/_chunks/index.mjs +648 -0
  35. package/dist/_chunks/server.mjs +256 -0
  36. package/dist/_cli/build.mjs +2 -2
  37. package/dist/_cli/dev.mjs +46 -130
  38. package/dist/_cli/index.mjs +1 -1
  39. package/dist/_cli/list.mjs +2 -2
  40. package/dist/_cli/prepare.mjs +2 -2
  41. package/dist/_cli/run.mjs +2 -2
  42. package/dist/cli/index.mjs +1 -1
  43. package/dist/index.mjs +94 -120
  44. package/dist/node_modules/cookie-es/dist/index.mjs +262 -0
  45. package/dist/node_modules/cookie-es/package.json +37 -0
  46. package/dist/node_modules/rendu/dist/index.mjs +380 -0
  47. package/dist/node_modules/rendu/package.json +47 -0
  48. package/dist/runtime/internal/task.mjs +1 -2
  49. package/dist/types/index.d.mts +2 -1
  50. package/dist/vite.mjs +103 -114
  51. package/lib/runtime/meta.mjs +18 -25
  52. package/package.json +9 -10
  53. package/dist/_build/assets.mjs +0 -235
  54. package/dist/_build/config.mjs +0 -124
  55. package/dist/_build/plugins.mjs +0 -1041
  56. package/dist/_build/rolldown.mjs +0 -494
  57. package/dist/_build/types.mjs +0 -268
  58. package/dist/node_modules/klona/dist/index.mjs +0 -81
  59. package/dist/node_modules/klona/full/index.mjs +0 -53
  60. package/dist/node_modules/klona/package.json +0 -74
  61. package/dist/node_modules/std-env/dist/index.mjs +0 -1
  62. package/dist/node_modules/std-env/package.json +0 -46
  63. /package/dist/{_deps → _chunks/_deps}/@jridgewell/gen-mapping.mjs +0 -0
  64. /package/dist/{_deps → _chunks/_deps}/@jridgewell/remapping.mjs +0 -0
  65. /package/dist/{_deps → _chunks/_deps}/@jridgewell/resolve-uri.mjs +0 -0
  66. /package/dist/{_deps → _chunks/_deps}/@jridgewell/sourcemap-codec.mjs +0 -0
  67. /package/dist/{_deps → _chunks/_deps}/@jridgewell/trace-mapping.mjs +0 -0
  68. /package/dist/{_deps → _chunks/_deps}/@pi0/vite-plugin-fullstack.mjs +0 -0
  69. /package/dist/{_deps → _chunks/_deps}/@rollup/plugin-alias.mjs +0 -0
  70. /package/dist/{_deps → _chunks/_deps}/@rollup/plugin-commonjs.mjs +0 -0
  71. /package/dist/{_deps → _chunks/_deps}/@rollup/plugin-inject.mjs +0 -0
  72. /package/dist/{_deps → _chunks/_deps}/@rollup/plugin-json.mjs +0 -0
  73. /package/dist/{_deps → _chunks/_deps}/@rollup/plugin-node-resolve.mjs +0 -0
  74. /package/dist/{_deps → _chunks/_deps}/@rollup/plugin-replace.mjs +0 -0
  75. /package/dist/{_deps → _chunks/_deps}/@rollup/pluginutils.mjs +0 -0
  76. /package/dist/{_deps → _chunks/_deps}/acorn.mjs +0 -0
  77. /package/dist/{_deps → _chunks/_deps}/chokidar.mjs +0 -0
  78. /package/dist/{_deps → _chunks/_deps}/citty.mjs +0 -0
  79. /package/dist/{_deps → _chunks/_deps}/commondir.mjs +0 -0
  80. /package/dist/{_deps → _chunks/_deps}/compatx.mjs +0 -0
  81. /package/dist/{_deps → _chunks/_deps}/confbox.mjs +0 -0
  82. /package/dist/{_deps → _chunks/_deps}/debug.mjs +0 -0
  83. /package/dist/{_deps → _chunks/_deps}/deepmerge.mjs +0 -0
  84. /package/dist/{_deps → _chunks/_deps}/depd.mjs +0 -0
  85. /package/dist/{_deps → _chunks/_deps}/dot-prop.mjs +0 -0
  86. /package/dist/{_deps → _chunks/_deps}/dotenv.mjs +0 -0
  87. /package/dist/{_deps → _chunks/_deps}/duplexer.mjs +0 -0
  88. /package/dist/{_deps → _chunks/_deps}/ee-first.mjs +0 -0
  89. /package/dist/{_deps → _chunks/_deps}/encodeurl.mjs +0 -0
  90. /package/dist/{_deps → _chunks/_deps}/escape-html.mjs +0 -0
  91. /package/dist/{_deps → _chunks/_deps}/escape-string-regexp.mjs +0 -0
  92. /package/dist/{_deps → _chunks/_deps}/estree-walker.mjs +0 -0
  93. /package/dist/{_deps → _chunks/_deps}/etag.mjs +0 -0
  94. /package/dist/{_deps → _chunks/_deps}/exsolve.mjs +0 -0
  95. /package/dist/{_deps → _chunks/_deps}/fdir.mjs +0 -0
  96. /package/dist/{_deps → _chunks/_deps}/fresh.mjs +0 -0
  97. /package/dist/{_deps → _chunks/_deps}/function-bind.mjs +0 -0
  98. /package/dist/{_deps → _chunks/_deps}/gzip-size.mjs +0 -0
  99. /package/dist/{_deps → _chunks/_deps}/hasown.mjs +0 -0
  100. /package/dist/{_deps → _chunks/_deps}/http-errors.mjs +0 -0
  101. /package/dist/{_deps → _chunks/_deps}/httpxy.mjs +0 -0
  102. /package/dist/{_deps → _chunks/_deps}/inherits.mjs +0 -0
  103. /package/dist/{_deps → _chunks/_deps}/is-core-module.mjs +0 -0
  104. /package/dist/{_deps → _chunks/_deps}/is-module.mjs +0 -0
  105. /package/dist/{_deps → _chunks/_deps}/is-reference.mjs +0 -0
  106. /package/dist/{_deps → _chunks/_deps}/js-tokens.mjs +0 -0
  107. /package/dist/{_deps → _chunks/_deps}/magic-string.mjs +0 -0
  108. /package/dist/{_deps → _chunks/_deps}/mime-db.mjs +0 -0
  109. /package/dist/{_deps → _chunks/_deps}/mime-types.mjs +0 -0
  110. /package/dist/{_deps → _chunks/_deps}/mime.mjs +0 -0
  111. /package/dist/{_deps → _chunks/_deps}/ms.mjs +0 -0
  112. /package/dist/{_deps → _chunks/_deps}/node-fetch-native.mjs +0 -0
  113. /package/dist/{_deps → _chunks/_deps}/on-finished.mjs +0 -0
  114. /package/dist/{_deps → _chunks/_deps}/parseurl.mjs +0 -0
  115. /package/dist/{_deps → _chunks/_deps}/path-parse.mjs +0 -0
  116. /package/dist/{_deps → _chunks/_deps}/perfect-debounce.mjs +0 -0
  117. /package/dist/{_deps → _chunks/_deps}/picomatch.mjs +0 -0
  118. /package/dist/{_deps → _chunks/_deps}/pretty-bytes.mjs +0 -0
  119. /package/dist/{_deps → _chunks/_deps}/quansync.mjs +0 -0
  120. /package/dist/{_deps → _chunks/_deps}/range-parser.mjs +0 -0
  121. /package/dist/{_deps → _chunks/_deps}/rc9.mjs +0 -0
  122. /package/dist/{_deps → _chunks/_deps}/readdirp.mjs +0 -0
  123. /package/dist/{_deps → _chunks/_deps}/resolve.mjs +0 -0
  124. /package/dist/{_deps → _chunks/_deps}/send.mjs +0 -0
  125. /package/dist/{_deps → _chunks/_deps}/serve-static.mjs +0 -0
  126. /package/dist/{_deps → _chunks/_deps}/setprototypeof.mjs +0 -0
  127. /package/dist/{_deps → _chunks/_deps}/statuses.mjs +0 -0
  128. /package/dist/{_deps → _chunks/_deps}/strip-literal.mjs +0 -0
  129. /package/dist/{_deps → _chunks/_deps}/supports-color.mjs +0 -0
  130. /package/dist/{_deps → _chunks/_deps}/tinyexec.mjs +0 -0
  131. /package/dist/{_deps → _chunks/_deps}/tinyglobby.mjs +0 -0
  132. /package/dist/{_deps → _chunks/_deps}/toidentifier.mjs +0 -0
  133. /package/dist/{_deps → _chunks/_deps}/ultrahtml.mjs +0 -0
  134. /package/dist/{_deps → _chunks/_deps}/unplugin.mjs +0 -0
  135. /package/dist/{_deps → _chunks/_deps}/webpack-virtual-modules.mjs +0 -0
  136. /package/dist/{_presets → _chunks/_presets}/_all.mjs +0 -0
  137. /package/dist/{_presets → _chunks/_presets}/_nitro.mjs +0 -0
  138. /package/dist/{_presets → _chunks/_presets}/_static.mjs +0 -0
  139. /package/dist/{_presets → _chunks/_presets}/_types.mjs +0 -0
  140. /package/dist/{_presets → _chunks/_presets}/alwaysdata.mjs +0 -0
  141. /package/dist/{_presets → _chunks/_presets}/aws-amplify.mjs +0 -0
  142. /package/dist/{_presets → _chunks/_presets}/aws-lambda.mjs +0 -0
  143. /package/dist/{_presets → _chunks/_presets}/bun.mjs +0 -0
  144. /package/dist/{_presets → _chunks/_presets}/cleavr.mjs +0 -0
  145. /package/dist/{_presets → _chunks/_presets}/digitalocean.mjs +0 -0
  146. /package/dist/{_presets → _chunks/_presets}/flightcontrol.mjs +0 -0
  147. /package/dist/{_presets → _chunks/_presets}/genezio.mjs +0 -0
  148. /package/dist/{_presets → _chunks/_presets}/heroku.mjs +0 -0
  149. /package/dist/{_presets → _chunks/_presets}/koyeb.mjs +0 -0
  150. /package/dist/{_presets → _chunks/_presets}/netlify.mjs +0 -0
  151. /package/dist/{_presets → _chunks/_presets}/node.mjs +0 -0
  152. /package/dist/{_presets → _chunks/_presets}/platform.mjs +0 -0
  153. /package/dist/{_presets → _chunks/_presets}/render.mjs +0 -0
  154. /package/dist/{_presets → _chunks/_presets}/standard.mjs +0 -0
  155. /package/dist/{_presets → _chunks/_presets}/stormkit.mjs +0 -0
  156. /package/dist/{_presets → _chunks/_presets}/winterjs.mjs +0 -0
  157. /package/dist/{_presets → _chunks/_presets}/zerops.mjs +0 -0
@@ -1,2290 +1,46 @@
1
- import { pathToFileURL } from 'node:url';
1
+ import { g as copyPublicAssets, s as scanHandlers, h as prettyPath, p as prepare, c as createNitro } from './prepare.mjs';
2
+ import 'node:url';
2
3
  import { colors } from 'consola/utils';
3
- import defu$1, { defu } from 'defu';
4
- import { m as mime } from '../_deps/mime.mjs';
5
- import { r as resolveNitroPath, p as prettyPath, s as scanUnprefixedPublicAssets, c as compressPublicAssets, w as writeFile, a as copyPublicAssets } from './assets.mjs';
6
- import { c as createRouter, a as addRoute, b as compileRouterToString, f as findRoute, d as findAllRoutes } from '../_deps/rou3.mjs';
7
- import { withLeadingSlash, withoutTrailingSlash, withTrailingSlash, parseURL, withBase, joinURL, withoutBase } from 'ufo';
8
- import { b as build$1 } from './build.mjs';
9
- import { a as scanAndSyncOptions, s as scanHandlers, r as runParallel } from './rolldown.mjs';
10
- import { z, P } from '../_deps/ultrahtml.mjs';
11
- import { a as resolve, j as join, n as normalize, r as relative, d as dirname$1, c as basename, i as isAbsolute } from '../_deps/pathe.mjs';
12
- import { fromNodeHandler, HTTPError, defineHandler, getRequestIP, getRequestURL, H3, toEventHandler, withBase as withBase$1 } from 'h3';
13
- import { version } from 'nitro/meta';
14
- import consola, { consola as consola$1 } from 'consola';
15
- import { readFile, rm, writeFile as writeFile$1, mkdir, readlink } from 'node:fs/promises';
16
- import { watch } from '../_deps/chokidar.mjs';
17
- import { serve, NodeRequest, sendNodeResponse } from 'srvx/node';
18
- import { d as debounce } from '../_deps/perfect-debounce.mjs';
19
- import { isDebug, isTest, isCI } from 'std-env';
20
- import { p as prepare } from './prepare.mjs';
21
- import './types.mjs';
22
- import { Hookable, createDebugger } from 'hookable';
23
- import { w as watchConfig, l as loadConfig } from '../_deps/c12.mjs';
24
- import { r as resolveCompatibilityDatesFromEnv, a as resolveCompatibilityDates, f as formatCompatibilityDate } from '../_deps/compatx.mjs';
25
- import { klona } from 'klona/full';
26
- import { runtimeDir, pkgDir, runtimeDependencies } from 'nitro/runtime/meta';
4
+ import { defu } from 'defu';
5
+ import '../_chunks/_deps/mime.mjs';
6
+ import 'ufo';
27
7
  import { existsSync, watch as watch$1 } from 'node:fs';
28
- import { e as escapeStringRegexp } from '../_deps/escape-string-regexp.mjs';
29
- import { r as resolveModuleExportNames, s as sanitizeFilePath } from '../_deps/mlly.mjs';
30
- import { f as findWorkspaceDir } from '../_deps/pkg-types.mjs';
31
- import { r as resolveModulePath } from '../_deps/exsolve.mjs';
32
- import { createJiti } from 'jiti';
33
- import { ofetch } from 'ofetch';
34
- import { c as createStorage } from './snapshot.mjs';
35
- import { hash } from 'ohash';
36
- import { c as createUnimport } from '../_deps/unimport.mjs';
8
+ import { readFile, rm, mkdir, writeFile, readlink } from 'node:fs/promises';
37
9
  import 'node:zlib';
38
- import { Worker } from 'node:worker_threads';
39
- import { Agent } from 'undici';
40
- import { s as serveStatic } from '../_deps/serve-static.mjs';
41
- import { c as createProxyServer } from '../_deps/httpxy.mjs';
42
- import { resolve as resolve$1, dirname, join as join$1 } from 'node:path';
43
- import { ErrorParser } from 'youch-core';
44
- import { Youch } from 'youch';
45
- import { SourceMapConsumer } from 'source-map';
46
- import { FastResponse } from 'srvx';
47
- import { a as alias } from '../_deps/@rollup/plugin-alias.mjs';
48
- import { i as inject } from '../_deps/@rollup/plugin-inject.mjs';
49
- import { b as baseBuildPlugins, r as replace } from './plugins.mjs';
50
- import { b as baseBuildConfig } from './config.mjs';
51
- import 'klona';
10
+ import 'node:worker_threads';
11
+ import consola from 'consola';
12
+ import 'h3';
13
+ import 'undici';
14
+ import 'nitro/meta';
15
+ import { NodeRequest, sendNodeResponse } from 'srvx/node';
16
+ import { a as NodeDevWorker, N as NitroDevApp } from '../_chunks/app.mjs';
17
+ import { runtimeDir, runtimeDependencies } from 'nitro/runtime/meta';
18
+ import { r as resolveModulePath } from '../_chunks/_deps/exsolve.mjs';
19
+ import 'ofetch';
20
+ import { s as sanitizeFilePath } from '../_chunks/_deps/mlly.mjs';
21
+ import { a as alias } from '../_chunks/_deps/@rollup/plugin-alias.mjs';
22
+ import { i as inject } from '../_chunks/_deps/@rollup/plugin-inject.mjs';
23
+ import { b as baseBuildConfig, a as baseBuildPlugins, r as replace, w as writeBuildInfo } from './info.mjs';
24
+ import { r as resolve, d as dirname, n as normalize, b as basename, a as relative, j as join, i as isAbsolute } from '../_chunks/_deps/pathe.mjs';
25
+ import { f as formatCompatibilityDate } from '../_chunks/_deps/compatx.mjs';
26
+ import 'hookable';
27
+ import 'jiti';
52
28
  import 'unstorage';
53
- import { w as writeBuildInfo } from './info.mjs';
29
+ import 'ohash';
30
+ import { a, T } from '../_chunks/_deps/std-env.mjs';
31
+ import '../_chunks/_deps/serve-static.mjs';
32
+ import { resolve as resolve$1, join as join$1 } from 'node:path';
33
+ import 'youch-core';
34
+ import 'youch';
35
+ import 'source-map';
36
+ import 'srvx';
54
37
  import { DevEnvironment } from 'vite';
38
+ import { watch } from '../_chunks/_deps/chokidar.mjs';
39
+ import { d as debounce } from '../_chunks/_deps/perfect-debounce.mjs';
55
40
  import { getRandomPort } from 'get-port-please';
56
41
  import { spawn } from 'node:child_process';
57
- import { a as assetsPlugin } from '../_deps/@pi0/vite-plugin-fullstack.mjs';
58
-
59
- const NitroDefaults = {
60
- // General
61
- compatibilityDate: "latest",
62
- debug: isDebug,
63
- logLevel: isTest ? 1 : 3,
64
- runtimeConfig: { app: {}, nitro: {} },
65
- // Dirs
66
- scanDirs: [],
67
- buildDir: ".nitro",
68
- output: {
69
- dir: "{{ rootDir }}/.output",
70
- serverDir: "{{ output.dir }}/server",
71
- publicDir: "{{ output.dir }}/public"
72
- },
73
- // Features
74
- experimental: {},
75
- future: {},
76
- storage: {},
77
- devStorage: {},
78
- bundledStorage: [],
79
- publicAssets: [],
80
- serverAssets: [],
81
- plugins: [],
82
- tasks: {},
83
- scheduledTasks: {},
84
- imports: false,
85
- virtual: {},
86
- compressPublicAssets: false,
87
- ignore: [],
88
- // Dev
89
- dev: false,
90
- devServer: { watch: [] },
91
- watchOptions: { ignoreInitial: true },
92
- devProxy: {},
93
- // Logging
94
- logging: {
95
- compressedSizes: true,
96
- buildSuccess: true
97
- },
98
- // Routing
99
- baseURL: process.env.NITRO_APP_BASE_URL || "/",
100
- handlers: [],
101
- devHandlers: [],
102
- errorHandler: void 0,
103
- routeRules: {},
104
- prerender: {
105
- autoSubfolderIndex: true,
106
- concurrency: 1,
107
- interval: 0,
108
- retry: 3,
109
- retryDelay: 500,
110
- failOnError: false,
111
- crawlLinks: false,
112
- ignore: [],
113
- routes: []
114
- },
115
- // Rollup
116
- builder: void 0,
117
- moduleSideEffects: ["unenv/polyfill/", resolve(runtimeDir, "polyfill/")],
118
- replace: {},
119
- node: true,
120
- sourceMap: true,
121
- esbuild: {
122
- options: {
123
- jsxFactory: "h",
124
- jsxFragment: "Fragment"
125
- }
126
- },
127
- // Advanced
128
- typescript: {
129
- strict: true,
130
- generateRuntimeConfigTypes: false,
131
- generateTsConfig: false,
132
- tsconfigPath: "types/tsconfig.json",
133
- internalPaths: false,
134
- tsConfig: {}
135
- },
136
- nodeModulesDirs: [],
137
- hooks: {},
138
- commands: {},
139
- // Framework
140
- framework: {
141
- name: "nitro",
142
- version: ""
143
- }
144
- };
145
-
146
- async function resolveAssetsOptions(options) {
147
- for (const publicAsset of options.publicAssets) {
148
- publicAsset.dir = resolve(options.srcDir, publicAsset.dir);
149
- publicAsset.baseURL = withLeadingSlash(
150
- withoutTrailingSlash(publicAsset.baseURL || "/")
151
- );
152
- }
153
- for (const dir of options.scanDirs) {
154
- const publicDir = resolve(dir, "public");
155
- if (!existsSync(publicDir)) {
156
- continue;
157
- }
158
- if (options.publicAssets.some((asset) => asset.dir === publicDir)) {
159
- continue;
160
- }
161
- options.publicAssets.push({ dir: publicDir });
162
- }
163
- for (const serverAsset of options.serverAssets) {
164
- serverAsset.dir = resolve(options.srcDir, serverAsset.dir);
165
- }
166
- options.serverAssets.push({
167
- baseName: "server",
168
- dir: resolve(options.srcDir, "assets")
169
- });
170
- for (const asset of options.publicAssets) {
171
- asset.baseURL = asset.baseURL || "/";
172
- const isTopLevel = asset.baseURL === "/";
173
- asset.fallthrough = asset.fallthrough ?? isTopLevel;
174
- const routeRule = options.routeRules[asset.baseURL + "/**"];
175
- asset.maxAge = routeRule?.cache?.maxAge ?? asset.maxAge ?? 0;
176
- if (asset.maxAge && !asset.fallthrough) {
177
- options.routeRules[asset.baseURL + "/**"] = defu(routeRule, {
178
- headers: {
179
- "cache-control": `public, max-age=${asset.maxAge}, immutable`
180
- }
181
- });
182
- }
183
- }
184
- }
185
-
186
- async function resolveCompatibilityOptions(options) {
187
- options.compatibilityDate = resolveCompatibilityDatesFromEnv(
188
- options.compatibilityDate
189
- );
190
- }
191
-
192
- async function resolveDatabaseOptions(options) {
193
- if (options.experimental.database && options.imports) {
194
- options.imports.presets.push({
195
- from: "nitro/runtime/internal/database",
196
- imports: ["useDatabase"]
197
- });
198
- if (options.dev && !options.database && !options.devDatabase) {
199
- options.devDatabase = {
200
- default: {
201
- connector: "sqlite",
202
- options: {
203
- cwd: options.rootDir
204
- }
205
- }
206
- };
207
- } else if (options.node && !options.database) {
208
- options.database = {
209
- default: {
210
- connector: "sqlite",
211
- options: {}
212
- }
213
- };
214
- }
215
- }
216
- }
217
-
218
- async function resolveExportConditionsOptions(options) {
219
- options.exportConditions = _resolveExportConditions(
220
- options.exportConditions || [],
221
- { dev: options.dev, node: options.node, wasm: options.experimental.wasm }
222
- );
223
- }
224
- function _resolveExportConditions(conditions, opts) {
225
- const resolvedConditions = [];
226
- resolvedConditions.push(opts.dev ? "development" : "production");
227
- resolvedConditions.push(...conditions);
228
- if (opts.node) {
229
- resolvedConditions.push("node");
230
- } else {
231
- resolvedConditions.push(
232
- "wintercg",
233
- "worker",
234
- "web",
235
- "browser",
236
- "workerd",
237
- "edge-light",
238
- "netlify",
239
- "edge-routine",
240
- "deno"
241
- );
242
- }
243
- if (opts.wasm) {
244
- resolvedConditions.push("wasm", "unwasm");
245
- }
246
- resolvedConditions.push("import", "default");
247
- return resolvedConditions.filter(
248
- (c, i) => resolvedConditions.indexOf(c) === i
249
- );
250
- }
251
-
252
- async function resolveImportsOptions(options) {
253
- if (options.imports === false) {
254
- return;
255
- }
256
- options.imports.presets ??= [];
257
- options.imports.presets.push(...getNitroImportsPreset());
258
- const h3Exports = await resolveModuleExportNames("h3", {
259
- url: import.meta.url
260
- });
261
- options.imports.presets ??= [];
262
- options.imports.presets.push({
263
- from: "h3",
264
- imports: h3Exports.filter((n) => !/^[A-Z]/.test(n) && n !== "use")
265
- });
266
- options.imports.dirs ??= [];
267
- options.imports.dirs.push(
268
- ...options.scanDirs.map((dir) => join(dir, "utils/**/*"))
269
- );
270
- if (Array.isArray(options.imports.exclude) && options.imports.exclude.length === 0) {
271
- options.imports.exclude.push(/[/\\]\.git[/\\]/);
272
- options.imports.exclude.push(options.buildDir);
273
- const scanDirsInNodeModules = options.scanDirs.map((dir) => dir.match(/(?<=\/)node_modules\/(.+)$/)?.[1]).filter(Boolean);
274
- options.imports.exclude.push(
275
- scanDirsInNodeModules.length > 0 ? new RegExp(
276
- `node_modules\\/(?!${scanDirsInNodeModules.map((dir) => escapeStringRegexp(dir)).join("|")})`
277
- ) : /[/\\]node_modules[/\\]/
278
- );
279
- }
280
- }
281
- function getNitroImportsPreset() {
282
- return [
283
- {
284
- from: "nitro/runtime/internal/app",
285
- imports: ["useNitroApp"]
286
- },
287
- {
288
- from: "nitro/runtime/internal/runtime-config",
289
- imports: ["useRuntimeConfig"]
290
- },
291
- {
292
- from: "nitro/runtime/internal/plugin",
293
- imports: ["defineNitroPlugin", "nitroPlugin"]
294
- },
295
- {
296
- from: "nitro/runtime/internal/cache",
297
- imports: [
298
- "defineCachedFunction",
299
- "defineCachedEventHandler",
300
- "defineCachedHandler",
301
- "cachedFunction",
302
- "cachedEventHandler"
303
- ]
304
- },
305
- {
306
- from: "nitro/runtime/internal/storage",
307
- imports: ["useStorage"]
308
- },
309
- {
310
- from: "nitro/runtime/internal/renderer",
311
- imports: ["defineRenderHandler"]
312
- },
313
- {
314
- from: "nitro/runtime/internal/meta",
315
- imports: ["defineRouteMeta"]
316
- },
317
- {
318
- from: "nitro/runtime/internal/route-rules",
319
- imports: ["getRouteRules"]
320
- },
321
- {
322
- from: "nitro/runtime/internal/context",
323
- imports: ["useRequest"]
324
- },
325
- {
326
- from: "nitro/runtime/internal/task",
327
- imports: ["defineTask", "runTask"]
328
- },
329
- {
330
- from: "nitro/runtime/internal/error/utils",
331
- imports: ["defineNitroErrorHandler"]
332
- },
333
- {
334
- from: "nitro/deps/ofetch",
335
- imports: ["$fetch"]
336
- }
337
- ];
338
- }
339
-
340
- async function resolveOpenAPIOptions(options) {
341
- if (!options.experimental.openAPI) {
342
- return;
343
- }
344
- if (!options.dev && !options.openAPI?.production) {
345
- return;
346
- }
347
- const shouldPrerender = !options.dev && options.openAPI?.production === "prerender";
348
- const handlersEnv = shouldPrerender ? "prerender" : "";
349
- const prerenderRoutes = [];
350
- const jsonRoute = options.openAPI?.route || "/_openapi.json";
351
- prerenderRoutes.push(jsonRoute);
352
- options.handlers.push({
353
- route: jsonRoute,
354
- env: handlersEnv,
355
- handler: join(runtimeDir, "internal/routes/openapi")
356
- });
357
- if (options.openAPI?.ui?.scalar !== false) {
358
- const scalarRoute = options.openAPI?.ui?.scalar?.route || "/_scalar";
359
- prerenderRoutes.push(scalarRoute);
360
- options.handlers.push({
361
- route: options.openAPI?.ui?.scalar?.route || "/_scalar",
362
- env: handlersEnv,
363
- handler: join(runtimeDir, "internal/routes/scalar")
364
- });
365
- }
366
- if (options.openAPI?.ui?.swagger !== false) {
367
- const swaggerRoute = options.openAPI?.ui?.swagger?.route || "/_swagger";
368
- prerenderRoutes.push(swaggerRoute);
369
- options.handlers.push({
370
- route: swaggerRoute,
371
- env: handlersEnv,
372
- handler: join(runtimeDir, "internal/routes/swagger")
373
- });
374
- }
375
- if (shouldPrerender) {
376
- options.prerender ??= {};
377
- options.prerender.routes ??= [];
378
- options.prerender.routes.push(...prerenderRoutes);
379
- }
380
- }
381
-
382
- const RESOLVE_EXTENSIONS = [".ts", ".js", ".mts", ".mjs", ".tsx", ".jsx"];
383
- async function resolvePathOptions(options) {
384
- options.rootDir = resolve(options.rootDir || ".") + "/";
385
- options.workspaceDir ||= await findWorkspaceDir(options.rootDir).catch(() => options.rootDir) + "/";
386
- for (const key of ["srcDir", "buildDir"]) {
387
- options[key] = resolve(options.rootDir, options[key] || ".");
388
- }
389
- options.alias ??= {};
390
- if (!options.static && !options.entry) {
391
- throw new Error(
392
- `Nitro entry is missing! Is "${options.preset}" preset correct?`
393
- );
394
- }
395
- if (options.entry) {
396
- options.entry = resolveNitroPath(options.entry, options);
397
- }
398
- options.output.dir = resolveNitroPath(
399
- options.output.dir || NitroDefaults.output.dir,
400
- options,
401
- options.rootDir
402
- ) + "/";
403
- options.output.publicDir = resolveNitroPath(
404
- options.output.publicDir || NitroDefaults.output.publicDir,
405
- options,
406
- options.rootDir
407
- ) + "/";
408
- options.output.serverDir = resolveNitroPath(
409
- options.output.serverDir || NitroDefaults.output.serverDir,
410
- options,
411
- options.rootDir
412
- ) + "/";
413
- options.nodeModulesDirs.push(resolve(options.rootDir, "node_modules"));
414
- options.nodeModulesDirs.push(resolve(options.workspaceDir, "node_modules"));
415
- options.nodeModulesDirs.push(resolve(pkgDir, "dist/node_modules"));
416
- options.nodeModulesDirs.push(resolve(pkgDir, "node_modules"));
417
- options.nodeModulesDirs.push(resolve(pkgDir, ".."));
418
- options.nodeModulesDirs = [
419
- ...new Set(
420
- // Adding trailing slash to optimize resolve performance (path is explicitly a dir)
421
- options.nodeModulesDirs.map((dir) => resolve(options.rootDir, dir) + "/")
422
- )
423
- ];
424
- options.plugins = options.plugins.map((p) => resolveNitroPath(p, options));
425
- options.scanDirs.unshift(options.srcDir);
426
- options.scanDirs = options.scanDirs.map(
427
- (dir) => resolve(options.srcDir, dir)
428
- );
429
- options.scanDirs = [...new Set(options.scanDirs.map((dir) => dir + "/"))];
430
- if (options.serverEntry) {
431
- options.serverEntry = resolveModulePath(
432
- resolveNitroPath(options.serverEntry, options),
433
- {
434
- from: options.scanDirs,
435
- extensions: RESOLVE_EXTENSIONS
436
- }
437
- );
438
- } else {
439
- const defaultServerEntry = resolveModulePath("./server", {
440
- from: options.scanDirs,
441
- extensions: RESOLVE_EXTENSIONS,
442
- try: true
443
- });
444
- if (defaultServerEntry) {
445
- options.serverEntry = defaultServerEntry;
446
- consola.info(
447
- `Using \`${prettyPath(defaultServerEntry)}\` as server entry.`
448
- );
449
- }
450
- }
451
- if (options.renderer?.entry) {
452
- options.renderer.entry = resolveModulePath(
453
- resolveNitroPath(options.renderer?.entry, options),
454
- {
455
- from: options.scanDirs,
456
- extensions: RESOLVE_EXTENSIONS
457
- }
458
- );
459
- }
460
- if (options.renderer?.template) {
461
- options.renderer.template = resolveModulePath(
462
- resolveNitroPath(options.renderer?.template, options),
463
- {
464
- from: options.scanDirs,
465
- extensions: [".html"]
466
- }
467
- );
468
- } else if (!options.renderer?.entry) {
469
- const defaultIndex = resolveModulePath("./index.html", {
470
- from: options.scanDirs,
471
- extensions: [".html"],
472
- try: true
473
- });
474
- if (defaultIndex) {
475
- options.renderer ??= {};
476
- options.renderer.template = defaultIndex;
477
- consola.info(
478
- `Using \`${prettyPath(defaultIndex)}\` as renderer template.`
479
- );
480
- }
481
- }
482
- if (options.renderer?.template && !options.renderer?.entry) {
483
- options.renderer ??= {};
484
- options.renderer.entry = join(
485
- runtimeDir,
486
- "internal/routes/renderer-template" + (options.dev ? ".dev" : "")
487
- );
488
- }
489
- }
490
-
491
- async function resolveRouteRulesOptions(options) {
492
- options.routeRules = defu(options.routeRules, options.routes || {});
493
- options.routeRules = normalizeRouteRules(options);
494
- }
495
- function normalizeRouteRules(config) {
496
- const normalizedRules = {};
497
- for (let path in config.routeRules) {
498
- const routeConfig = config.routeRules[path];
499
- path = withLeadingSlash(path);
500
- const routeRules = {
501
- ...routeConfig,
502
- redirect: void 0,
503
- proxy: void 0
504
- };
505
- if (routeConfig.redirect) {
506
- routeRules.redirect = {
507
- // @ts-ignore
508
- to: "/",
509
- status: 307,
510
- ...typeof routeConfig.redirect === "string" ? { to: routeConfig.redirect } : routeConfig.redirect
511
- };
512
- if (path.endsWith("/**")) {
513
- routeRules.redirect._redirectStripBase = path.slice(0, -3);
514
- }
515
- }
516
- if (routeConfig.proxy) {
517
- routeRules.proxy = typeof routeConfig.proxy === "string" ? { to: routeConfig.proxy } : routeConfig.proxy;
518
- if (path.endsWith("/**")) {
519
- routeRules.proxy._proxyStripBase = path.slice(0, -3);
520
- }
521
- }
522
- if (routeConfig.cors) {
523
- routeRules.headers = {
524
- "access-control-allow-origin": "*",
525
- "access-control-allow-methods": "*",
526
- "access-control-allow-headers": "*",
527
- "access-control-max-age": "0",
528
- ...routeRules.headers
529
- };
530
- }
531
- if (routeConfig.swr) {
532
- routeRules.cache = routeRules.cache || {};
533
- routeRules.cache.swr = true;
534
- if (typeof routeConfig.swr === "number") {
535
- routeRules.cache.maxAge = routeConfig.swr;
536
- }
537
- }
538
- if (routeConfig.cache === false) {
539
- routeRules.cache = false;
540
- }
541
- normalizedRules[path] = routeRules;
542
- }
543
- return normalizedRules;
544
- }
545
-
546
- async function resolveRuntimeConfigOptions(options) {
547
- options.runtimeConfig = normalizeRuntimeConfig(options);
548
- }
549
- function normalizeRuntimeConfig(config) {
550
- provideFallbackValues(config.runtimeConfig || {});
551
- const runtimeConfig = defu$1(
552
- config.runtimeConfig,
553
- {
554
- app: {
555
- baseURL: config.baseURL
556
- },
557
- nitro: {
558
- envExpansion: config.experimental?.envExpansion,
559
- openAPI: config.openAPI
560
- }
561
- }
562
- );
563
- runtimeConfig.nitro.routeRules = config.routeRules;
564
- checkSerializableRuntimeConfig(runtimeConfig);
565
- return runtimeConfig;
566
- }
567
- function provideFallbackValues(obj) {
568
- for (const key in obj) {
569
- if (obj[key] === void 0 || obj[key] === null) {
570
- obj[key] = "";
571
- } else if (typeof obj[key] === "object") {
572
- provideFallbackValues(obj[key]);
573
- }
574
- }
575
- }
576
- function checkSerializableRuntimeConfig(obj, path = []) {
577
- if (isPrimitiveValue(obj)) {
578
- return;
579
- }
580
- for (const key in obj) {
581
- const value = obj[key];
582
- if (value === null || value === void 0 || isPrimitiveValue(value)) {
583
- continue;
584
- }
585
- if (Array.isArray(value)) {
586
- for (const [index, item] of value.entries())
587
- checkSerializableRuntimeConfig(item, [...path, `${key}[${index}]`]);
588
- } else if (typeof value === "object" && value.constructor === Object && (!value.constructor?.name || value.constructor.name === "Object")) {
589
- checkSerializableRuntimeConfig(value, [...path, key]);
590
- } else {
591
- console.warn(
592
- `Runtime config option \`${[...path, key].join(".")}\` may not be able to be serialized.`
593
- );
594
- }
595
- }
596
- }
597
- function isPrimitiveValue(value) {
598
- return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
599
- }
600
-
601
- async function resolveStorageOptions(options) {
602
- const fsMounts = {
603
- root: resolve(options.rootDir),
604
- src: resolve(options.srcDir),
605
- build: resolve(options.buildDir),
606
- cache: resolve(options.buildDir, "cache")
607
- };
608
- for (const p in fsMounts) {
609
- options.devStorage[p] = options.devStorage[p] || {
610
- driver: "fs",
611
- readOnly: p === "root" || p === "src",
612
- base: fsMounts[p]
613
- };
614
- }
615
- if (options.dev && options.storage.data === void 0 && options.devStorage.data === void 0) {
616
- options.devStorage.data = {
617
- driver: "fs",
618
- base: resolve(options.rootDir, ".data/kv")
619
- };
620
- } else if (options.node && options.storage.data === void 0) {
621
- options.storage.data = {
622
- driver: "fsLite",
623
- base: "./.data/kv"
624
- };
625
- }
626
- }
627
-
628
- async function resolveURLOptions(options) {
629
- options.baseURL = withLeadingSlash(withTrailingSlash(options.baseURL));
630
- }
631
-
632
- async function resolveErrorOptions(options) {
633
- if (!options.errorHandler) {
634
- options.errorHandler = [];
635
- } else if (!Array.isArray(options.errorHandler)) {
636
- options.errorHandler = [options.errorHandler];
637
- }
638
- options.errorHandler.push(
639
- join(runtimeDir, `internal/error/${options.dev ? "dev" : "prod"}`)
640
- );
641
- }
642
-
643
- const common = {
644
- meta: {
645
- name: "nitro-common",
646
- url: import.meta.url
647
- },
648
- alias: {
649
- "buffer/": "node:buffer",
650
- "buffer/index": "node:buffer",
651
- "buffer/index.js": "node:buffer",
652
- "string_decoder/": "node:string_decoder",
653
- "process/": "node:process"
654
- }
655
- };
656
- const nodeless = {
657
- meta: {
658
- name: "nitro-nodeless",
659
- url: import.meta.url
660
- },
661
- inject: {
662
- global: "unenv/polyfill/globalthis",
663
- process: "node:process",
664
- Buffer: ["node:buffer", "Buffer"],
665
- clearImmediate: ["node:timers", "clearImmediate"],
666
- setImmediate: ["node:timers", "setImmediate"],
667
- performance: "unenv/polyfill/performance",
668
- PerformanceObserver: ["node:perf_hooks", "PerformanceObserver"],
669
- BroadcastChannel: ["node:worker_threads", "BroadcastChannel"]
670
- },
671
- polyfill: [
672
- "unenv/polyfill/globalthis-global",
673
- "unenv/polyfill/process",
674
- "unenv/polyfill/buffer",
675
- "unenv/polyfill/timers"
676
- ]
677
- };
678
- async function resolveUnenv(options) {
679
- options.unenv ??= [];
680
- if (!Array.isArray(options.unenv)) {
681
- options.unenv = [options.unenv];
682
- }
683
- options.unenv = options.unenv.filter(Boolean);
684
- if (!options.node) {
685
- options.unenv.unshift(nodeless);
686
- }
687
- options.unenv.unshift(common);
688
- }
689
-
690
- async function resolveBuilder(options) {
691
- if (!options.builder) {
692
- options.builder = process.env.NITRO_BUILDER || "rollup";
693
- }
694
- if (options.builder === "rolldown") {
695
- try {
696
- await import('rolldown');
697
- } catch {
698
- throw new Error(
699
- `Builder "rolldown" is not available. Make sure to install "rolldown" package.`
700
- );
701
- }
702
- } else if (options.builder === "vite") {
703
- try {
704
- await import('vite');
705
- } catch {
706
- throw new Error(
707
- `Builder "vite" is not available. Make sure to install "vite" package.`
708
- );
709
- }
710
- }
711
- if (!["rollup", "rolldown", "vite"].includes(options.builder)) {
712
- throw new Error(`Builder "${options.builder}" is not supported.`);
713
- }
714
- }
715
-
716
- const configResolvers = [
717
- resolveCompatibilityOptions,
718
- resolvePathOptions,
719
- resolveImportsOptions,
720
- resolveRouteRulesOptions,
721
- resolveDatabaseOptions,
722
- resolveExportConditionsOptions,
723
- resolveRuntimeConfigOptions,
724
- resolveOpenAPIOptions,
725
- resolveURLOptions,
726
- resolveAssetsOptions,
727
- resolveStorageOptions,
728
- resolveErrorOptions,
729
- resolveUnenv,
730
- resolveBuilder
731
- ];
732
- async function loadOptions(configOverrides = {}, opts = {}) {
733
- const options = await _loadUserConfig(configOverrides, opts);
734
- for (const resolver of configResolvers) {
735
- await resolver(options);
736
- }
737
- return options;
738
- }
739
- async function _loadUserConfig(configOverrides = {}, opts = {}) {
740
- configOverrides = klona(configOverrides);
741
- globalThis.defineNitroConfig = globalThis.defineNitroConfig || ((c) => c);
742
- let compatibilityDate = configOverrides.compatibilityDate || opts.compatibilityDate || (process.env.NITRO_COMPATIBILITY_DATE || process.env.SERVER_COMPATIBILITY_DATE || process.env.COMPATIBILITY_DATE);
743
- const { resolvePreset } = await import('../_presets/index.mjs');
744
- let preset = configOverrides.preset || process.env.NITRO_PRESET || process.env.SERVER_PRESET;
745
- const _dotenv = opts.dotenv ?? (configOverrides.dev && { fileName: [".env", ".env.local"] });
746
- const loadedConfig = await (opts.watch ? watchConfig : loadConfig)({
747
- name: "nitro",
748
- cwd: configOverrides.rootDir,
749
- dotenv: _dotenv,
750
- extend: { extendKey: ["extends", "preset"] },
751
- defaults: NitroDefaults,
752
- jitiOptions: {
753
- alias: {
754
- nitropack: "nitro/config",
755
- "nitro/config": "nitro/config"
756
- }
757
- },
758
- async overrides({ rawConfigs }) {
759
- const getConf = (key) => configOverrides[key] ?? rawConfigs.main?.[key] ?? rawConfigs.rc?.[key] ?? rawConfigs.packageJson?.[key];
760
- if (!compatibilityDate) {
761
- compatibilityDate = getConf("compatibilityDate");
762
- }
763
- const framework = getConf("framework");
764
- const isCustomFramework = framework?.name && framework.name !== "nitro";
765
- if (!preset) {
766
- preset = getConf("preset");
767
- }
768
- if (configOverrides.dev) {
769
- preset = preset && preset !== "nitro-dev" ? await resolvePreset(preset, {
770
- static: getConf("static"),
771
- dev: true,
772
- compatibilityDate: compatibilityDate || "latest"
773
- }).then((p) => p?._meta?.name || "nitro-dev").catch(() => "nitro-dev") : "nitro-dev";
774
- } else if (!preset) {
775
- preset = await resolvePreset("", {
776
- static: getConf("static"),
777
- dev: false,
778
- compatibilityDate: compatibilityDate || "latest"
779
- }).then((p) => p?._meta?.name);
780
- }
781
- return {
782
- ...configOverrides,
783
- preset,
784
- typescript: {
785
- generateRuntimeConfigTypes: !isCustomFramework,
786
- ...getConf("typescript"),
787
- ...configOverrides.typescript
788
- }
789
- };
790
- },
791
- async resolve(id) {
792
- const preset2 = await resolvePreset(id, {
793
- static: configOverrides.static,
794
- compatibilityDate: compatibilityDate || "latest",
795
- dev: configOverrides.dev
796
- });
797
- if (preset2) {
798
- return {
799
- config: klona(preset2)
800
- };
801
- }
802
- },
803
- ...opts.c12
804
- });
805
- const options = klona(loadedConfig.config);
806
- options._config = configOverrides;
807
- options._c12 = loadedConfig;
808
- const _presetName = (loadedConfig.layers || []).find((l) => l.config?._meta?.name)?.config?._meta?.name || preset;
809
- options.preset = _presetName;
810
- options.compatibilityDate = resolveCompatibilityDates(
811
- compatibilityDate,
812
- options.compatibilityDate
813
- );
814
- if (options.dev && options.preset !== "nitro-dev") {
815
- consola.info(`Using \`${options.preset}\` emulation in development mode.`);
816
- }
817
- return options;
818
- }
819
-
820
- async function updateNitroConfig(nitro, config) {
821
- nitro.options.routeRules = normalizeRouteRules(
822
- config.routeRules ? config : nitro.options
823
- );
824
- nitro.options.runtimeConfig = normalizeRuntimeConfig(
825
- config.runtimeConfig ? config : nitro.options
826
- );
827
- await nitro.hooks.callHook("rollup:reload");
828
- consola.success("Nitro config hot reloaded!");
829
- }
830
-
831
- async function installModules(nitro) {
832
- const _modules = [...nitro.options.modules || []];
833
- const modules = await Promise.all(
834
- _modules.map((mod) => _resolveNitroModule(mod, nitro.options))
835
- );
836
- const _installedURLs = /* @__PURE__ */ new Set();
837
- for (const mod of modules) {
838
- if (mod._url) {
839
- if (_installedURLs.has(mod._url)) {
840
- continue;
841
- }
842
- _installedURLs.add(mod._url);
843
- }
844
- await mod.setup(nitro);
845
- }
846
- }
847
- async function _resolveNitroModule(mod, nitroOptions) {
848
- let _url;
849
- if (typeof mod === "string") {
850
- globalThis.defineNitroModule = // @ts-ignore
851
- globalThis.defineNitroModule || ((mod2) => mod2);
852
- const jiti = createJiti(nitroOptions.rootDir, {
853
- alias: nitroOptions.alias
854
- });
855
- const _modPath = jiti.esmResolve(mod);
856
- _url = _modPath;
857
- mod = await jiti.import(_modPath, { default: true });
858
- }
859
- if (typeof mod === "function") {
860
- mod = { setup: mod };
861
- }
862
- if (!mod.setup) {
863
- mod.setup = () => {
864
- };
865
- }
866
- return {
867
- _url,
868
- ...mod
869
- };
870
- }
871
-
872
- async function runTask(taskEvent, opts) {
873
- const ctx = await _getTasksContext(opts);
874
- const result = await ctx.devFetch(`/_nitro/tasks/${taskEvent.name}`, {
875
- method: "POST",
876
- body: taskEvent
877
- });
878
- return result;
879
- }
880
- async function listTasks(opts) {
881
- const ctx = await _getTasksContext(opts);
882
- const res = await ctx.devFetch("/_nitro/tasks");
883
- return res.tasks;
884
- }
885
- function addNitroTasksVirtualFile(nitro) {
886
- nitro.options.virtual["#nitro-internal-virtual/tasks"] = () => {
887
- const _scheduledTasks = Object.entries(nitro.options.scheduledTasks || {}).map(([cron, _tasks]) => {
888
- const tasks = (Array.isArray(_tasks) ? _tasks : [_tasks]).filter(
889
- (name) => {
890
- if (!nitro.options.tasks[name]) {
891
- nitro.logger.warn(`Scheduled task \`${name}\` is not defined!`);
892
- return false;
893
- }
894
- return true;
895
- }
896
- );
897
- return { cron, tasks };
898
- }).filter((e) => e.tasks.length > 0);
899
- const scheduledTasks = _scheduledTasks.length > 0 ? _scheduledTasks : false;
900
- return (
901
- /* js */
902
- `
903
- export const scheduledTasks = ${JSON.stringify(scheduledTasks)};
904
-
905
- export const tasks = {
906
- ${Object.entries(nitro.options.tasks).map(
907
- ([name, task]) => `"${name}": {
908
- meta: {
909
- description: ${JSON.stringify(task.description)},
910
- },
911
- resolve: ${task.handler ? `() => import("${normalize(
912
- task.handler
913
- )}").then(r => r.default || r)` : "undefined"},
914
- }`
915
- ).join(",\n")}
916
- };`
917
- );
918
- };
919
- }
920
- const _devHint = `(is dev server running?)`;
921
- async function _getTasksContext(opts) {
922
- const cwd = resolve(process.cwd(), opts?.cwd || ".");
923
- const outDir = resolve(cwd, opts?.buildDir || ".nitro");
924
- const buildInfoPath = resolve(outDir, "nitro.json");
925
- if (!existsSync(buildInfoPath)) {
926
- throw new Error(`Missing info file: \`${buildInfoPath}\` ${_devHint}`);
927
- }
928
- const buildInfo = JSON.parse(
929
- await readFile(buildInfoPath, "utf8")
930
- );
931
- if (!buildInfo.dev?.pid || !buildInfo.dev?.workerAddress) {
932
- throw new Error(
933
- `Missing dev server info in: \`${buildInfoPath}\` ${_devHint}`
934
- );
935
- }
936
- if (!_pidIsRunning(buildInfo.dev.pid)) {
937
- throw new Error(`Dev server is not running (pid: ${buildInfo.dev.pid})`);
938
- }
939
- const devFetch = ofetch.create({
940
- baseURL: `http://${buildInfo.dev.workerAddress.host || "localhost"}:${buildInfo.dev.workerAddress.port || "3000"}`,
941
- // @ts-expect-error
942
- socketPath: buildInfo.dev.workerAddress.socketPath
943
- });
944
- return {
945
- buildInfo,
946
- devFetch
947
- };
948
- }
949
- function _pidIsRunning(pid) {
950
- try {
951
- process.kill(pid, 0);
952
- return true;
953
- } catch {
954
- return false;
955
- }
956
- }
957
-
958
- const isGlobalMiddleware = (h) => !h.method && (!h.route || h.route === "/**");
959
- function initNitroRouting(nitro) {
960
- const envConditions = new Set(
961
- [
962
- nitro.options.dev ? "dev" : "prod",
963
- nitro.options.preset,
964
- nitro.options.preset === "nitro-prerender" ? "prerender" : void 0
965
- ].filter(Boolean)
966
- );
967
- const matchesEnv = (h) => {
968
- const hEnv = Array.isArray(h.env) ? h.env : [h.env];
969
- const envs = hEnv.filter(Boolean);
970
- return envs.length === 0 || envs.some((env) => envConditions.has(env));
971
- };
972
- const routes = new Router();
973
- const routeRules = new Router(
974
- true
975
- /* matchAll */
976
- );
977
- const globalMiddleware = [];
978
- const routedMiddleware = new Router(
979
- true
980
- /* matchAll */
981
- );
982
- const warns = /* @__PURE__ */ new Set();
983
- const sync = () => {
984
- routeRules._update(
985
- Object.entries(nitro.options.routeRules).map(([route, data]) => ({
986
- route,
987
- method: "",
988
- data: {
989
- ...data,
990
- _route: route
991
- }
992
- }))
993
- );
994
- const _routes = [
995
- ...nitro.scannedHandlers,
996
- ...nitro.options.handlers
997
- ].filter((h) => h && !h.middleware && matchesEnv(h));
998
- if (nitro.options.renderer?.entry) {
999
- const existingWildcard = _routes.findIndex(
1000
- (h) => /^\/\*\*(:.+)?$/.test(h.route) && (!h.method || h.method === "GET")
1001
- );
1002
- if (existingWildcard !== -1) {
1003
- const h = _routes[existingWildcard];
1004
- const warn = `The renderer will override \`${relative(".", h.handler)}\` (route: \`${h.route}\`). Use a more specific route or different HTTP method.`;
1005
- if (!warns.has(warn)) {
1006
- warns.add(warn);
1007
- nitro.logger.warn(warn);
1008
- }
1009
- _routes.splice(existingWildcard, 1);
1010
- }
1011
- _routes.push({
1012
- route: "/**",
1013
- lazy: true,
1014
- handler: nitro.options.renderer?.entry
1015
- });
1016
- }
1017
- routes._update(
1018
- _routes.map((h) => ({
1019
- ...h,
1020
- method: h.method || "",
1021
- data: handlerWithImportHash(h)
1022
- }))
1023
- );
1024
- const _middleware = [
1025
- ...nitro.scannedHandlers,
1026
- ...nitro.options.handlers
1027
- ].filter((h) => h && h.middleware && matchesEnv(h));
1028
- if (nitro.options.serveStatic) {
1029
- _middleware.unshift({
1030
- route: "/**",
1031
- middleware: true,
1032
- handler: join(runtimeDir, "internal/static")
1033
- });
1034
- }
1035
- globalMiddleware.splice(
1036
- 0,
1037
- globalMiddleware.length,
1038
- ..._middleware.filter((h) => isGlobalMiddleware(h)).map((m) => handlerWithImportHash(m))
1039
- );
1040
- routedMiddleware._update(
1041
- _middleware.filter((h) => !isGlobalMiddleware(h)).map((h) => ({
1042
- ...h,
1043
- method: h.method || "",
1044
- data: handlerWithImportHash(h)
1045
- }))
1046
- );
1047
- };
1048
- nitro.routing = Object.freeze({
1049
- sync,
1050
- routes,
1051
- routeRules,
1052
- globalMiddleware,
1053
- routedMiddleware
1054
- });
1055
- }
1056
- function handlerWithImportHash(h) {
1057
- const id = (h.lazy ? "_lazy_" : "_") + hash(h.handler).replace(/-/g, "").slice(0, 6);
1058
- return { ...h, _importHash: id };
1059
- }
1060
- class Router {
1061
- #routes;
1062
- #router;
1063
- #compiled;
1064
- constructor(matchAll) {
1065
- this._update([]);
1066
- }
1067
- get routes() {
1068
- return this.#routes;
1069
- }
1070
- _update(routes) {
1071
- this.#routes = routes;
1072
- this.#router = createRouter();
1073
- this.#compiled = void 0;
1074
- for (const route of routes) {
1075
- addRoute(this.#router, route.method, route.route, route.data);
1076
- }
1077
- }
1078
- hasRoutes() {
1079
- return this.#routes.length > 0;
1080
- }
1081
- compileToString(opts) {
1082
- return this.#compiled || (this.#compiled = compileRouterToString(this.#router, void 0, opts));
1083
- }
1084
- match(method, path) {
1085
- return findRoute(this.#router, method, path)?.data;
1086
- }
1087
- matchAll(method, path) {
1088
- return findAllRoutes(this.#router, method, path).map(
1089
- (route) => route.data
1090
- );
1091
- }
1092
- }
1093
-
1094
- async function createNitro(config = {}, opts = {}) {
1095
- const options = await loadOptions(config, opts);
1096
- const nitro = {
1097
- options,
1098
- hooks: new Hookable(),
1099
- vfs: {},
1100
- routing: {},
1101
- logger: consola$1.withTag("nitro"),
1102
- scannedHandlers: [],
1103
- close: () => nitro.hooks.callHook("close"),
1104
- storage: void 0,
1105
- async updateConfig(config2) {
1106
- updateNitroConfig(nitro, config2);
1107
- }
1108
- };
1109
- initNitroRouting(nitro);
1110
- await scanAndSyncOptions(nitro);
1111
- nitro.storage = await createStorage(nitro);
1112
- nitro.hooks.hook("close", async () => {
1113
- await nitro.storage.dispose();
1114
- });
1115
- if (nitro.options.debug) {
1116
- createDebugger(nitro.hooks, { tag: "nitro" });
1117
- }
1118
- if (nitro.options.logLevel !== void 0) {
1119
- nitro.logger.level = nitro.options.logLevel;
1120
- }
1121
- nitro.hooks.addHooks(nitro.options.hooks);
1122
- addNitroTasksVirtualFile(nitro);
1123
- await installModules(nitro);
1124
- if (nitro.options.imports) {
1125
- nitro.unimport = createUnimport(nitro.options.imports);
1126
- await nitro.unimport.init();
1127
- nitro.options.virtual["#imports"] = () => nitro.unimport?.toExports() || "";
1128
- nitro.options.virtual["#nitro"] = 'export * from "#imports"';
1129
- }
1130
- await scanHandlers(nitro);
1131
- nitro.routing.sync();
1132
- return nitro;
1133
- }
1134
-
1135
- const allowedExtensions = /* @__PURE__ */ new Set(["", ".json"]);
1136
- const linkParents$1 = /* @__PURE__ */ new Map();
1137
- const HTML_ENTITIES = {
1138
- "&lt;": "<",
1139
- "&gt;": ">",
1140
- "&amp;": "&",
1141
- "&apos;": "'",
1142
- "&quot;": '"'
1143
- };
1144
- function escapeHtml(text) {
1145
- return text.replace(
1146
- /&(lt|gt|amp|apos|quot);/g,
1147
- (ch) => HTML_ENTITIES[ch] || ch
1148
- );
1149
- }
1150
- async function extractLinks(html, from, res, crawlLinks) {
1151
- const links = [];
1152
- const _links = [];
1153
- if (crawlLinks) {
1154
- await z(P(html), (node) => {
1155
- if (!node.attributes?.href) {
1156
- return;
1157
- }
1158
- const link = escapeHtml(node.attributes.href);
1159
- if (!decodeURIComponent(link).startsWith("#") && allowedExtensions.has(getExtension(link))) {
1160
- _links.push(link);
1161
- }
1162
- });
1163
- }
1164
- const header = res.headers.get("x-nitro-prerender") || "";
1165
- _links.push(...header.split(",").map((i) => decodeURIComponent(i.trim())));
1166
- for (const link of _links.filter(Boolean)) {
1167
- const _link = parseURL(link);
1168
- if (_link.protocol || _link.host) {
1169
- continue;
1170
- }
1171
- if (!_link.pathname.startsWith("/")) {
1172
- const fromURL = new URL(from, "http://localhost");
1173
- _link.pathname = new URL(_link.pathname, fromURL).pathname;
1174
- }
1175
- links.push(_link.pathname + _link.search);
1176
- }
1177
- for (const link of links) {
1178
- const _parents = linkParents$1.get(link);
1179
- if (_parents) {
1180
- _parents.add(from);
1181
- } else {
1182
- linkParents$1.set(link, /* @__PURE__ */ new Set([from]));
1183
- }
1184
- }
1185
- return links;
1186
- }
1187
- const EXT_REGEX = /\.[\da-z]+$/;
1188
- function getExtension(link) {
1189
- const pathname = parseURL(link).pathname;
1190
- return (pathname.match(EXT_REGEX) || [])[0] || "";
1191
- }
1192
- function formatPrerenderRoute(route) {
1193
- let str = ` \u251C\u2500 ${route.route} (${route.generateTimeMS}ms)`;
1194
- if (route.error) {
1195
- const parents = linkParents$1.get(route.route);
1196
- const errorColor = colors[route.error.status === 404 ? "yellow" : "red"];
1197
- const errorLead = parents?.size ? "\u251C\u2500\u2500" : "\u2514\u2500\u2500";
1198
- str += `
1199
- \u2502 ${errorLead} ${errorColor(route.error.message)}`;
1200
- if (parents?.size) {
1201
- str += `
1202
- ${[...parents.values()].map((link) => ` \u2502 \u2514\u2500\u2500 Linked from ${link}`).join("\n")}`;
1203
- }
1204
- }
1205
- if (route.skip) {
1206
- str += colors.gray(" (skipped)");
1207
- }
1208
- return colors.gray(str);
1209
- }
1210
- function matchesIgnorePattern(path, pattern) {
1211
- if (typeof pattern === "string") {
1212
- return path.startsWith(pattern);
1213
- }
1214
- if (typeof pattern === "function") {
1215
- return pattern(path) === true;
1216
- }
1217
- if (pattern instanceof RegExp) {
1218
- return pattern.test(path);
1219
- }
1220
- return false;
1221
- }
1222
-
1223
- const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
1224
- const linkParents = /* @__PURE__ */ new Map();
1225
- async function prerender(nitro) {
1226
- if (nitro.options.noPublicDir) {
1227
- nitro.logger.warn(
1228
- "Skipping prerender since `noPublicDir` option is enabled."
1229
- );
1230
- return;
1231
- }
1232
- if (nitro.options.builder === "vite") {
1233
- nitro.logger.warn(
1234
- "Skipping prerender since not supported with vite builder yet..."
1235
- );
1236
- return;
1237
- }
1238
- const routes = new Set(nitro.options.prerender.routes);
1239
- const prerenderRulePaths = Object.entries(nitro.options.routeRules).filter(([path2, options]) => options.prerender && !path2.includes("*")).map((e) => e[0]);
1240
- for (const route of prerenderRulePaths) {
1241
- routes.add(route);
1242
- }
1243
- await nitro.hooks.callHook("prerender:routes", routes);
1244
- if (routes.size === 0) {
1245
- if (nitro.options.prerender.crawlLinks) {
1246
- routes.add("/");
1247
- } else {
1248
- return;
1249
- }
1250
- }
1251
- nitro.logger.info("Initializing prerenderer");
1252
- nitro._prerenderedRoutes = [];
1253
- nitro._prerenderMeta = nitro._prerenderMeta || {};
1254
- const prerendererConfig = {
1255
- ...nitro.options._config,
1256
- static: false,
1257
- rootDir: nitro.options.rootDir,
1258
- logLevel: 0,
1259
- preset: "nitro-prerender"
1260
- };
1261
- await nitro.hooks.callHook("prerender:config", prerendererConfig);
1262
- const nitroRenderer = await createNitro(prerendererConfig);
1263
- const prerenderStartTime = Date.now();
1264
- await nitro.hooks.callHook("prerender:init", nitroRenderer);
1265
- let path = relative(nitro.options.output.dir, nitro.options.output.publicDir);
1266
- if (!path.startsWith(".")) {
1267
- path = `./${path}`;
1268
- }
1269
- nitroRenderer.options.commands.preview = `npx serve ${path}`;
1270
- nitroRenderer.options.output.dir = nitro.options.output.dir;
1271
- await build$1(nitroRenderer);
1272
- const serverFilename = typeof nitroRenderer.options.rollupConfig?.output?.entryFileNames === "string" ? nitroRenderer.options.rollupConfig.output.entryFileNames : "index.mjs";
1273
- const serverEntrypoint = resolve(
1274
- nitroRenderer.options.output.serverDir,
1275
- serverFilename
1276
- );
1277
- const { closePrerenderer, appFetch } = await import(pathToFileURL(serverEntrypoint).href);
1278
- const routeRules = createRouter();
1279
- for (const [route, rules] of Object.entries(nitro.options.routeRules)) {
1280
- addRoute(routeRules, void 0, route, rules);
1281
- }
1282
- const _getRouteRules = (path2) => defu(
1283
- {},
1284
- ...findAllRoutes(routeRules, void 0, path2).map((r) => r.data).reverse()
1285
- );
1286
- const generatedRoutes = /* @__PURE__ */ new Set();
1287
- const failedRoutes = /* @__PURE__ */ new Set();
1288
- const skippedRoutes = /* @__PURE__ */ new Set();
1289
- const displayedLengthWarns = /* @__PURE__ */ new Set();
1290
- const publicAssetBases = nitro.options.publicAssets.filter(
1291
- (a) => !!a.baseURL && a.baseURL !== "/" && !a.fallthrough
1292
- ).map((a) => withTrailingSlash(a.baseURL));
1293
- const scannedPublicAssets = nitro.options.prerender.ignoreUnprefixedPublicAssets ? new Set(await scanUnprefixedPublicAssets(nitro)) : /* @__PURE__ */ new Set();
1294
- const canPrerender = (route = "/") => {
1295
- if (generatedRoutes.has(route) || skippedRoutes.has(route)) {
1296
- return false;
1297
- }
1298
- for (const pattern of nitro.options.prerender.ignore) {
1299
- if (matchesIgnorePattern(route, pattern)) {
1300
- return false;
1301
- }
1302
- }
1303
- if (publicAssetBases.some((base) => route.startsWith(base))) {
1304
- return false;
1305
- }
1306
- if (scannedPublicAssets.has(route)) {
1307
- return false;
1308
- }
1309
- if (_getRouteRules(route).prerender === false) {
1310
- return false;
1311
- }
1312
- return true;
1313
- };
1314
- const canWriteToDisk = (route) => {
1315
- if (route.route.includes("?")) {
1316
- return false;
1317
- }
1318
- const FS_MAX_SEGMENT = 255;
1319
- const FS_MAX_PATH = 1024;
1320
- const FS_MAX_PATH_PUBLIC_HTML = FS_MAX_PATH - (nitro.options.output.publicDir.length + 10);
1321
- if ((route.route.length >= FS_MAX_PATH_PUBLIC_HTML || route.route.split("/").some((s) => s.length > FS_MAX_SEGMENT)) && !displayedLengthWarns.has(route)) {
1322
- displayedLengthWarns.add(route);
1323
- const _route = route.route.slice(0, 60) + "...";
1324
- if (route.route.length >= FS_MAX_PATH_PUBLIC_HTML) {
1325
- nitro.logger.warn(
1326
- `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}\`.`
1327
- );
1328
- } else {
1329
- nitro.logger.warn(
1330
- `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.`
1331
- );
1332
- return false;
1333
- }
1334
- }
1335
- return true;
1336
- };
1337
- const generateRoute = async (route) => {
1338
- const start = Date.now();
1339
- route = decodeURI(route);
1340
- if (!canPrerender(route)) {
1341
- skippedRoutes.add(route);
1342
- return;
1343
- }
1344
- generatedRoutes.add(route);
1345
- const _route = { route };
1346
- const encodedRoute = encodeURI(route);
1347
- const res = await appFetch(withBase(encodedRoute, nitro.options.baseURL), {
1348
- headers: [["x-nitro-prerender", encodedRoute]]
1349
- // TODO
1350
- // retry: nitro.options.prerender.retry,
1351
- // retryDelay: nitro.options.prerender.retryDelay,
1352
- });
1353
- let dataBuff = Buffer.from(await res.arrayBuffer());
1354
- Object.defineProperty(_route, "contents", {
1355
- get: () => {
1356
- return dataBuff ? dataBuff.toString("utf8") : void 0;
1357
- },
1358
- set(value) {
1359
- if (dataBuff) {
1360
- dataBuff = Buffer.from(value);
1361
- }
1362
- }
1363
- });
1364
- Object.defineProperty(_route, "data", {
1365
- get: () => {
1366
- return dataBuff ? dataBuff.buffer : void 0;
1367
- },
1368
- set(value) {
1369
- if (dataBuff) {
1370
- dataBuff = Buffer.from(value);
1371
- }
1372
- }
1373
- });
1374
- const redirectCodes = [301, 302, 303, 304, 307, 308];
1375
- if (![200, ...redirectCodes].includes(res.status)) {
1376
- _route.error = new Error(`[${res.status}] ${res.statusText}`);
1377
- _route.error.status = res.status;
1378
- _route.error.statusText = res.statusText;
1379
- }
1380
- _route.generateTimeMS = Date.now() - start;
1381
- const contentType = res.headers.get("content-type") || "";
1382
- const isImplicitHTML = !route.endsWith(".html") && contentType.includes("html") && !JsonSigRx.test(dataBuff.subarray(0, 32).toString("utf8"));
1383
- const routeWithIndex = route.endsWith("/") ? route + "index" : route;
1384
- const htmlPath = route.endsWith("/") || nitro.options.prerender.autoSubfolderIndex ? joinURL(route, "index.html") : route + ".html";
1385
- _route.fileName = withoutBase(
1386
- isImplicitHTML ? htmlPath : routeWithIndex,
1387
- nitro.options.baseURL
1388
- );
1389
- const inferredContentType = mime.getType(_route.fileName) || "text/plain";
1390
- _route.contentType = contentType || inferredContentType;
1391
- await nitro.hooks.callHook("prerender:generate", _route, nitro);
1392
- if (_route.contentType !== inferredContentType) {
1393
- nitro._prerenderMeta[_route.fileName] ||= {};
1394
- nitro._prerenderMeta[_route.fileName].contentType = _route.contentType;
1395
- }
1396
- if (_route.error) {
1397
- failedRoutes.add(_route);
1398
- }
1399
- if (_route.skip || _route.error) {
1400
- await nitro.hooks.callHook("prerender:route", _route);
1401
- nitro.logger.log(formatPrerenderRoute(_route));
1402
- dataBuff = void 0;
1403
- return _route;
1404
- }
1405
- if (canWriteToDisk(_route)) {
1406
- const filePath = join(nitro.options.output.publicDir, _route.fileName);
1407
- await writeFile(filePath, dataBuff);
1408
- nitro._prerenderedRoutes.push(_route);
1409
- } else {
1410
- _route.skip = true;
1411
- }
1412
- if (!_route.error && (isImplicitHTML || route.endsWith(".html"))) {
1413
- const extractedLinks = await extractLinks(
1414
- dataBuff.toString("utf8"),
1415
- route,
1416
- res,
1417
- nitro.options.prerender.crawlLinks
1418
- );
1419
- for (const _link of extractedLinks) {
1420
- if (canPrerender(_link)) {
1421
- routes.add(_link);
1422
- }
1423
- }
1424
- }
1425
- await nitro.hooks.callHook("prerender:route", _route);
1426
- nitro.logger.log(formatPrerenderRoute(_route));
1427
- dataBuff = void 0;
1428
- return _route;
1429
- };
1430
- nitro.logger.info(
1431
- nitro.options.prerender.crawlLinks ? `Prerendering ${routes.size} initial routes with crawler` : `Prerendering ${routes.size} routes`
1432
- );
1433
- await runParallel(routes, generateRoute, {
1434
- concurrency: nitro.options.prerender.concurrency,
1435
- interval: nitro.options.prerender.interval
1436
- });
1437
- await closePrerenderer();
1438
- await nitro.hooks.callHook("prerender:done", {
1439
- prerenderedRoutes: nitro._prerenderedRoutes,
1440
- failedRoutes: [...failedRoutes]
1441
- });
1442
- if (nitro.options.prerender.failOnError && failedRoutes.size > 0) {
1443
- nitro.logger.log("\nErrors prerendering:");
1444
- for (const route of failedRoutes) {
1445
- const parents = linkParents.get(route.route);
1446
- parents?.size ? `
1447
- ${[...parents.values()].map((link) => colors.gray(` \u2502 \u2514\u2500\u2500 Linked from ${link}`)).join("\n")}` : "";
1448
- nitro.logger.log(formatPrerenderRoute(route));
1449
- }
1450
- nitro.logger.log("");
1451
- throw new Error("Exiting due to prerender errors.");
1452
- }
1453
- const prerenderTimeInMs = Date.now() - prerenderStartTime;
1454
- nitro.logger.info(
1455
- `Prerendered ${nitro._prerenderedRoutes.length} routes in ${prerenderTimeInMs / 1e3} seconds`
1456
- );
1457
- if (nitro.options.compressPublicAssets) {
1458
- await compressPublicAssets(nitro);
1459
- }
1460
- }
1461
-
1462
- function createHTTPProxy(defaults = {}) {
1463
- const proxy = createProxyServer(defaults);
1464
- proxy.on("proxyReq", (proxyReq, req) => {
1465
- if (!proxyReq.hasHeader("x-forwarded-for")) {
1466
- const address = req.socket.remoteAddress;
1467
- if (address) {
1468
- proxyReq.appendHeader("x-forwarded-for", address);
1469
- }
1470
- }
1471
- if (!proxyReq.hasHeader("x-forwarded-port")) {
1472
- const localPort = req?.socket?.localPort;
1473
- if (localPort) {
1474
- proxyReq.setHeader("x-forwarded-port", req.socket.localPort);
1475
- }
1476
- }
1477
- if (!proxyReq.hasHeader("x-forwarded-Proto")) {
1478
- const encrypted = req?.connection?.encrypted;
1479
- proxyReq.setHeader("x-forwarded-proto", encrypted ? "https" : "http");
1480
- }
1481
- });
1482
- return {
1483
- proxy,
1484
- async handleEvent(event, opts) {
1485
- try {
1486
- return await fromNodeHandler(
1487
- (req, res) => proxy.web(req, res, opts)
1488
- )(event);
1489
- } catch (error) {
1490
- event.res.headers.set("refresh", "3");
1491
- throw new HTTPError({
1492
- status: 503,
1493
- message: "Dev server is unavailable.",
1494
- cause: error
1495
- });
1496
- }
1497
- }
1498
- };
1499
- }
1500
- function fetchAddress(addr, input, inputInit) {
1501
- let url;
1502
- let init;
1503
- if (input instanceof Request) {
1504
- url = new URL(input.url);
1505
- init = {
1506
- method: input.method,
1507
- headers: input.headers,
1508
- body: input.body,
1509
- ...inputInit
1510
- };
1511
- } else {
1512
- url = new URL(input);
1513
- init = inputInit;
1514
- }
1515
- init = {
1516
- duplex: "half",
1517
- redirect: "manual",
1518
- ...init
1519
- };
1520
- if (addr.socketPath) {
1521
- url.protocol = "http:";
1522
- return fetch(url, {
1523
- ...init,
1524
- ...fetchSocketOptions(addr.socketPath)
1525
- });
1526
- }
1527
- const origin = `http://${addr.host}${addr.port ? `:${addr.port}` : ""}`;
1528
- const outURL = new URL(url.pathname + url.search, origin);
1529
- return fetch(outURL, init);
1530
- }
1531
- function fetchSocketOptions(socketPath) {
1532
- if ("Bun" in globalThis) {
1533
- return { unix: socketPath };
1534
- }
1535
- if ("Deno" in globalThis) {
1536
- return {
1537
- // @ts-ignore
1538
- client: Deno.createHttpClient({
1539
- // @ts-ignore Missing types?
1540
- transport: "unix",
1541
- path: socketPath
1542
- })
1543
- };
1544
- }
1545
- return {
1546
- dispatcher: new Agent({ connect: { socketPath } })
1547
- };
1548
- }
1549
-
1550
- class NodeDevWorker {
1551
- closed = false;
1552
- #name;
1553
- #entry;
1554
- #data;
1555
- #hooks;
1556
- #worker;
1557
- #address;
1558
- #proxy;
1559
- #messageListeners;
1560
- constructor(opts) {
1561
- this.#name = opts.name;
1562
- this.#entry = opts.entry;
1563
- this.#data = opts.data;
1564
- this.#hooks = opts.hooks;
1565
- this.#proxy = createHTTPProxy();
1566
- this.#messageListeners = /* @__PURE__ */ new Set();
1567
- this.#initWorker();
1568
- }
1569
- get ready() {
1570
- return Boolean(
1571
- !this.closed && this.#address && this.#proxy && this.#worker
1572
- );
1573
- }
1574
- // #region Public methods
1575
- async fetch(input, init) {
1576
- for (let i = 0; i < 5 && !(this.#address && this.#proxy); i++) {
1577
- await new Promise((r) => setTimeout(r, 100 * Math.pow(2, i)));
1578
- }
1579
- if (!(this.#address && this.#proxy)) {
1580
- return new Response("Dev worker is unavailable", { status: 503 });
1581
- }
1582
- return fetchAddress(this.#address, input, init);
1583
- }
1584
- upgrade(req, socket, head) {
1585
- if (!this.ready) {
1586
- return;
1587
- }
1588
- return this.#proxy.proxy.ws(
1589
- req,
1590
- socket,
1591
- { target: this.#address, xfwd: true },
1592
- head
1593
- );
1594
- }
1595
- sendMessage(message) {
1596
- if (!this.#worker) {
1597
- throw new Error(
1598
- "Dev worker should be initialized before sending messages."
1599
- );
1600
- }
1601
- this.#worker.postMessage(message);
1602
- }
1603
- onMessage(listener) {
1604
- this.#messageListeners.add(listener);
1605
- }
1606
- offMessage(listener) {
1607
- this.#messageListeners.delete(listener);
1608
- }
1609
- async close(cause) {
1610
- if (this.closed) {
1611
- return;
1612
- }
1613
- this.closed = true;
1614
- this.#hooks.onClose?.(this, cause);
1615
- this.#hooks = {};
1616
- const onError = (error) => consola.error(error);
1617
- await this.#closeWorker().catch(onError);
1618
- await this.#closeProxy().catch(onError);
1619
- await this.#closeSocket().catch(onError);
1620
- }
1621
- [Symbol.for("nodejs.util.inspect.custom")]() {
1622
- const status = this.closed ? "closed" : this.ready ? "ready" : "pending";
1623
- return `NodeDevWorker#${this.#name}(${status})`;
1624
- }
1625
- // #endregion
1626
- // #region Private methods
1627
- #initWorker() {
1628
- if (!existsSync(this.#entry)) {
1629
- this.close(`worker entry not found in "${this.#entry}".`);
1630
- return;
1631
- }
1632
- const worker = new Worker(this.#entry, {
1633
- env: {
1634
- ...process.env
1635
- },
1636
- workerData: {
1637
- name: this.#name,
1638
- ...this.#data
1639
- }
1640
- });
1641
- worker.once("exit", (code) => {
1642
- worker._exitCode = code;
1643
- this.close(`worker exited with code ${code}`);
1644
- });
1645
- worker.once("error", (error) => {
1646
- consola.error(`Worker error:`, error);
1647
- this.close(error);
1648
- });
1649
- worker.on("message", (message) => {
1650
- if (message?.address) {
1651
- this.#address = message.address;
1652
- this.#hooks.onReady?.(this, this.#address);
1653
- }
1654
- for (const listener of this.#messageListeners) {
1655
- listener(message);
1656
- }
1657
- });
1658
- this.#worker = worker;
1659
- }
1660
- async #closeProxy() {
1661
- this.#proxy?.proxy?.close(() => {
1662
- });
1663
- this.#proxy = void 0;
1664
- }
1665
- async #closeSocket() {
1666
- const socketPath = this.#address?.socketPath;
1667
- if (socketPath && socketPath[0] !== "\0" && !socketPath.startsWith(String.raw`\\.\pipe`)) {
1668
- await rm(socketPath).catch(() => {
1669
- });
1670
- }
1671
- this.#address = void 0;
1672
- }
1673
- async #closeWorker() {
1674
- if (!this.#worker) {
1675
- return;
1676
- }
1677
- this.#worker.postMessage({ event: "shutdown" });
1678
- if (!this.#worker._exitCode && !isTest && !isCI) {
1679
- await new Promise((resolve) => {
1680
- const gracefulShutdownTimeoutMs = Number.parseInt(process.env.NITRO_SHUTDOWN_TIMEOUT || "", 10) || 5e3;
1681
- const timeout = setTimeout(() => {
1682
- if (process.env.DEBUG) {
1683
- consola.warn(`force closing dev worker...`);
1684
- }
1685
- }, gracefulShutdownTimeoutMs);
1686
- this.#worker?.on("message", (message) => {
1687
- if (message.event === "exit") {
1688
- clearTimeout(timeout);
1689
- resolve();
1690
- }
1691
- });
1692
- });
1693
- }
1694
- this.#worker.removeAllListeners();
1695
- await this.#worker.terminate().catch((error) => {
1696
- consola.error(error);
1697
- });
1698
- this.#worker = void 0;
1699
- }
1700
- // #endregion
1701
- }
1702
-
1703
- function createVFSHandler(nitro) {
1704
- return defineHandler(async (event) => {
1705
- const { socket } = event.runtime?.node?.req || {};
1706
- const isUnixSocket = (
1707
- // No network addresses
1708
- !socket?.remoteAddress && !socket?.localAddress && // Empty address object
1709
- Object.keys(socket?.address?.() || {}).length === 0 && // Socket is readable/writable but has no port info
1710
- socket?.readable && socket?.writable && !socket?.remotePort
1711
- );
1712
- const ip = getRequestIP(event, { xForwardedFor: isUnixSocket });
1713
- const isLocalRequest = ip && /^::1$|^127\.\d+\.\d+\.\d+$/.test(ip);
1714
- if (!isLocalRequest) {
1715
- throw new HTTPError({
1716
- statusText: `Forbidden IP: "${ip || "?"}"`,
1717
- status: 403
1718
- });
1719
- }
1720
- const vfsEntries = {
1721
- ...nitro.vfs,
1722
- ...nitro.options.virtual
1723
- };
1724
- const url = event.context.params?._ || "";
1725
- const isJson = url.endsWith(".json") || event.req.headers.get("accept")?.includes("application/json");
1726
- const id = decodeURIComponent(url.replace(/^(\.json)?\/?/, "") || "");
1727
- if (id && !(id in vfsEntries)) {
1728
- throw new HTTPError({ message: "File not found", status: 404 });
1729
- }
1730
- let content = id ? vfsEntries[id] : void 0;
1731
- if (typeof content === "function") {
1732
- content = await content();
1733
- }
1734
- if (isJson) {
1735
- return {
1736
- rootDir: nitro.options.rootDir,
1737
- entries: Object.keys(vfsEntries).map((id2) => ({
1738
- id: id2,
1739
- path: "/_vfs.json/" + encodeURIComponent(id2)
1740
- })),
1741
- current: id ? {
1742
- id,
1743
- content
1744
- } : null
1745
- };
1746
- }
1747
- const directories = { [nitro.options.rootDir]: {} };
1748
- const fpaths = Object.keys(vfsEntries);
1749
- for (const item of fpaths) {
1750
- const segments = item.replace(nitro.options.rootDir, "").split("/").filter(Boolean);
1751
- let currentDir = item.startsWith(nitro.options.rootDir) ? directories[nitro.options.rootDir] : directories;
1752
- for (const segment of segments) {
1753
- if (!currentDir[segment]) {
1754
- currentDir[segment] = {};
1755
- }
1756
- currentDir = currentDir[segment];
1757
- }
1758
- }
1759
- const generateHTML = (directory, path = []) => Object.entries(directory).map(([fname, value = {}]) => {
1760
- const subpath = [...path, fname];
1761
- const key = subpath.join("/");
1762
- const encodedUrl = encodeURIComponent(key);
1763
- const linkClass = url === `/${encodedUrl}` ? "bg-gray-700 text-white" : "hover:bg-gray-800 text-gray-200";
1764
- return Object.keys(value).length === 0 ? `
1765
- <li class="flex flex-nowrap">
1766
- <a href="/_vfs/${encodedUrl}" class="w-full text-sm px-2 py-1 border-b border-gray-10 ${linkClass}">
1767
- ${fname}
1768
- </a>
1769
- </li>
1770
- ` : `
1771
- <li>
1772
- <details ${url.startsWith(`/${encodedUrl}`) ? "open" : ""}>
1773
- <summary class="w-full text-sm px-2 py-1 border-b border-gray-10 hover:bg-gray-800 text-gray-200">
1774
- ${fname}
1775
- </summary>
1776
- <ul class="ml-4">
1777
- ${generateHTML(value, subpath)}
1778
- </ul>
1779
- </details>
1780
- </li>
1781
- `;
1782
- }).join("");
1783
- const rootDirectory = directories[nitro.options.rootDir];
1784
- delete directories[nitro.options.rootDir];
1785
- const items = generateHTML(rootDirectory, [nitro.options.rootDir]) + generateHTML(directories);
1786
- const files = `
1787
- <div class="h-full overflow-auto border-r border-gray:10">
1788
- <p class="text-white text-bold text-center py-1 opacity-50">Virtual Files</p>
1789
- <ul class="flex flex-col">${items}</ul>
1790
- </div>
1791
- `;
1792
- const file = id ? editorTemplate({
1793
- readOnly: true,
1794
- language: id.endsWith("html") ? "html" : "javascript",
1795
- theme: "vs-dark",
1796
- value: content,
1797
- wordWrap: "wordWrapColumn",
1798
- wordWrapColumn: 80
1799
- }) : `
1800
- <div class="w-full h-full flex opacity-50">
1801
- <h1 class="text-white m-auto">Select a virtual file to inspect</h1>
1802
- </div>
1803
- `;
1804
- event.res.headers.set("Content-Type", "text/html; charset=utf-8");
1805
- return (
1806
- /* html */
1807
- `
1808
- <!doctype html>
1809
- <html>
1810
- <head>
1811
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@unocss/reset/tailwind.min.css" />
1812
- <link rel="stylesheet" data-name="vs/editor/editor.main" href="${vsUrl}/editor/editor.main.min.css">
1813
- <script src="https://cdn.jsdelivr.net/npm/@unocss/runtime"><\/script>
1814
- <style>
1815
- html {
1816
- background: #1E1E1E;
1817
- color: white;
1818
- }
1819
- [un-cloak] {
1820
- display: none;
1821
- }
1822
- </style>
1823
- </head>
1824
- <body class="bg-[#1E1E1E]">
1825
- <div un-cloak class="h-screen grid grid-cols-[300px_1fr]">
1826
- ${files}
1827
- ${file}
1828
- </div>
1829
- </body>
1830
- </html>`
1831
- );
1832
- });
1833
- }
1834
- const monacoVersion = "0.30.0";
1835
- const monacoUrl = `https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/${monacoVersion}/min`;
1836
- const vsUrl = `${monacoUrl}/vs`;
1837
- const editorTemplate = (options) => `
1838
- <div id="editor" class="min-h-screen w-full h-full"></div>
1839
- <script src="${vsUrl}/loader.min.js"><\/script>
1840
- <script>
1841
- require.config({ paths: { vs: '${vsUrl}' } })
1842
-
1843
- const proxy = URL.createObjectURL(new Blob([\`
1844
- self.MonacoEnvironment = { baseUrl: '${monacoUrl}' }
1845
- importScripts('${vsUrl}/base/worker/workerMain.min.js')
1846
- \`], { type: 'text/javascript' }))
1847
- window.MonacoEnvironment = { getWorkerUrl: () => proxy }
1848
-
1849
- setTimeout(() => {
1850
- require(['vs/editor/editor.main'], function () {
1851
- monaco.editor.create(document.getElementById('editor'), ${JSON.stringify(
1852
- options
1853
- )})
1854
- })
1855
- }, 0);
1856
- <\/script>
1857
- `;
1858
-
1859
- function defineNitroErrorHandler(handler) {
1860
- return handler;
1861
- }
1862
-
1863
- const devErrorHandler = defineNitroErrorHandler(
1864
- async function defaultNitroErrorHandler(error, event) {
1865
- const res = await defaultHandler(error, event);
1866
- return new FastResponse(
1867
- typeof res.body === "string" ? res.body : JSON.stringify(res.body, null, 2),
1868
- res
1869
- );
1870
- }
1871
- );
1872
- async function defaultHandler(error, event, opts) {
1873
- const isSensitive = error.unhandled;
1874
- const status = error.status || 500;
1875
- const url = getRequestURL(event, { xForwardedHost: true, xForwardedProto: true });
1876
- if (status === 404) {
1877
- const baseURL = import.meta.baseURL || "/";
1878
- if (/^\/[^/]/.test(baseURL) && !url.pathname.startsWith(baseURL)) {
1879
- const redirectTo = `${baseURL}${url.pathname.slice(1)}${url.search}`;
1880
- return {
1881
- status: 302,
1882
- statusText: "Found",
1883
- headers: { location: redirectTo },
1884
- body: `Redirecting...`
1885
- };
1886
- }
1887
- }
1888
- await loadStackTrace(error).catch(consola.error);
1889
- const youch = new Youch();
1890
- if (isSensitive && !opts?.silent) {
1891
- const tags = [error.unhandled && "[unhandled]"].filter(Boolean).join(" ");
1892
- const ansiError = await (await youch.toANSI(error)).replaceAll(process.cwd(), ".");
1893
- consola.error(
1894
- `[request error] ${tags} [${event.req.method}] ${url}
1895
-
1896
- `,
1897
- ansiError
1898
- );
1899
- }
1900
- const useJSON = opts?.json || !event.req.headers.get("accept")?.includes("text/html");
1901
- const headers = {
1902
- "content-type": useJSON ? "application/json" : "text/html",
1903
- // Prevent browser from guessing the MIME types of resources.
1904
- "x-content-type-options": "nosniff",
1905
- // Prevent error page from being embedded in an iframe
1906
- "x-frame-options": "DENY",
1907
- // Prevent browsers from sending the Referer header
1908
- "referrer-policy": "no-referrer",
1909
- // Disable the execution of any js
1910
- "content-security-policy": "script-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'self';"
1911
- };
1912
- if (status === 404 || !event.res.headers.has("cache-control")) {
1913
- headers["cache-control"] = "no-cache";
1914
- }
1915
- const body = useJSON ? {
1916
- error: true,
1917
- url,
1918
- status,
1919
- statusText: error.statusText,
1920
- message: error.message,
1921
- data: error.data,
1922
- stack: error.stack?.split("\n").map((line) => line.trim())
1923
- } : await youch.toHTML(error, {
1924
- request: {
1925
- url: url.href,
1926
- method: event.req.method,
1927
- headers: Object.fromEntries(event.req.headers.entries())
1928
- }
1929
- });
1930
- return {
1931
- status,
1932
- statusText: error.statusText,
1933
- headers,
1934
- body
1935
- };
1936
- }
1937
- async function loadStackTrace(error) {
1938
- if (!(error instanceof Error)) {
1939
- return;
1940
- }
1941
- const parsed = await new ErrorParser().defineSourceLoader(sourceLoader).parse(error);
1942
- const stack = error.message + "\n" + parsed.frames.map((frame) => fmtFrame(frame)).join("\n");
1943
- Object.defineProperty(error, "stack", { value: stack });
1944
- if (error.cause) {
1945
- await loadStackTrace(error.cause).catch(consola.error);
1946
- }
1947
- }
1948
- async function sourceLoader(frame) {
1949
- if (!frame.fileName || frame.fileType !== "fs" || frame.type === "native") {
1950
- return;
1951
- }
1952
- if (frame.type === "app") {
1953
- const rawSourceMap = await readFile(`${frame.fileName}.map`, "utf8").catch(() => {
1954
- });
1955
- if (rawSourceMap) {
1956
- const consumer = await new SourceMapConsumer(rawSourceMap);
1957
- const originalPosition = consumer.originalPositionFor({ line: frame.lineNumber, column: frame.columnNumber });
1958
- if (originalPosition.source && originalPosition.line) {
1959
- frame.fileName = resolve$1(dirname(frame.fileName), originalPosition.source);
1960
- frame.lineNumber = originalPosition.line;
1961
- frame.columnNumber = originalPosition.column || 0;
1962
- }
1963
- }
1964
- }
1965
- const contents = await readFile(frame.fileName, "utf8").catch(() => {
1966
- });
1967
- return contents ? { contents } : void 0;
1968
- }
1969
- function fmtFrame(frame) {
1970
- if (frame.type === "native") {
1971
- return frame.raw;
1972
- }
1973
- const src = `${frame.fileName || ""}:${frame.lineNumber}:${frame.columnNumber})`;
1974
- return frame.functionName ? `at ${frame.functionName} (${src}` : `at ${src}`;
1975
- }
1976
-
1977
- class NitroDevApp {
1978
- nitro;
1979
- fetch;
1980
- constructor(nitro, catchAllHandler) {
1981
- this.nitro = nitro;
1982
- const app = this.#createApp(catchAllHandler);
1983
- this.fetch = app.fetch.bind(app);
1984
- }
1985
- #createApp(catchAllHandler) {
1986
- const app = new H3({
1987
- debug: true,
1988
- onError: async (error, event) => {
1989
- const errorHandler = this.nitro.options.devErrorHandler || devErrorHandler;
1990
- await loadStackTrace(error).catch(() => {
1991
- });
1992
- return errorHandler(error, event, {
1993
- defaultHandler: defaultHandler
1994
- });
1995
- }
1996
- });
1997
- for (const h of this.nitro.options.devHandlers) {
1998
- const handler = toEventHandler(h.handler);
1999
- if (!handler) {
2000
- this.nitro.logger.warn("Invalid dev handler:", h);
2001
- continue;
2002
- }
2003
- if (h.middleware || !h.route) {
2004
- if (h.route) {
2005
- app.use(h.route, handler, { method: h.method });
2006
- } else {
2007
- app.use(handler, { method: h.method });
2008
- }
2009
- } else {
2010
- app.on(h.method || "", h.route, handler, { meta: h.meta });
2011
- }
2012
- }
2013
- app.get("/_vfs/**", createVFSHandler(this.nitro));
2014
- for (const asset of this.nitro.options.publicAssets) {
2015
- const assetRoute = joinURL(
2016
- this.nitro.options.runtimeConfig.app.baseURL,
2017
- asset.baseURL || "/",
2018
- "**"
2019
- );
2020
- let handler = fromNodeHandler(
2021
- // @ts-expect-error (HTTP2 types)
2022
- serveStatic(asset.dir, { dotfiles: "allow" })
2023
- );
2024
- if (asset.baseURL?.length || 0 > 1) {
2025
- handler = withBase$1(asset.baseURL, handler);
2026
- }
2027
- app.use(assetRoute, handler);
2028
- }
2029
- const routes = Object.keys(this.nitro.options.devProxy).sort().reverse();
2030
- for (const route of routes) {
2031
- let opts = this.nitro.options.devProxy[route];
2032
- if (typeof opts === "string") {
2033
- opts = { target: opts };
2034
- }
2035
- const proxy = createHTTPProxy(opts);
2036
- app.all(route, proxy.handleEvent);
2037
- }
2038
- if (catchAllHandler) {
2039
- app.all("/**", catchAllHandler);
2040
- }
2041
- return app;
2042
- }
2043
- }
2044
-
2045
- function createDevServer(nitro) {
2046
- return new NitroDevServer(nitro);
2047
- }
2048
- class NitroDevServer extends NitroDevApp {
2049
- #entry;
2050
- #workerData = {};
2051
- #listeners = [];
2052
- #watcher;
2053
- #workers = [];
2054
- #workerIdCtr = 0;
2055
- #workerError;
2056
- #building = true;
2057
- // Assume initial build will start soon
2058
- #buildError;
2059
- #messageListeners = /* @__PURE__ */ new Set();
2060
- constructor(nitro) {
2061
- super(nitro, async (event) => {
2062
- const worker = await this.#getWorker();
2063
- if (!worker) {
2064
- return this.#generateError();
2065
- }
2066
- return worker.fetch(event.req);
2067
- });
2068
- for (const key of Object.getOwnPropertyNames(NitroDevServer.prototype)) {
2069
- const value = this[key];
2070
- if (typeof value === "function" && key !== "constructor") {
2071
- this[key] = value.bind(this);
2072
- }
2073
- }
2074
- this.#entry = resolve(
2075
- nitro.options.output.dir,
2076
- nitro.options.output.serverDir,
2077
- "index.mjs"
2078
- );
2079
- nitro.hooks.hook("close", () => this.close());
2080
- nitro.hooks.hook("dev:start", () => {
2081
- this.#building = true;
2082
- this.#buildError = void 0;
2083
- });
2084
- nitro.hooks.hook("dev:reload", (payload) => {
2085
- this.#buildError = void 0;
2086
- this.#building = false;
2087
- if (payload?.entry) {
2088
- this.#entry = payload.entry;
2089
- }
2090
- if (payload?.workerData) {
2091
- this.#workerData = payload.workerData;
2092
- }
2093
- this.reload();
2094
- });
2095
- nitro.hooks.hook("dev:error", (cause) => {
2096
- this.#buildError = cause;
2097
- this.#building = false;
2098
- for (const worker of this.#workers) {
2099
- worker.close();
2100
- }
2101
- });
2102
- if (nitro.options.devServer.watch.length > 0) {
2103
- const debouncedReload = debounce(() => this.reload());
2104
- this.#watcher = watch(
2105
- nitro.options.devServer.watch,
2106
- nitro.options.watchOptions
2107
- );
2108
- this.#watcher.on("add", debouncedReload).on("change", debouncedReload);
2109
- }
2110
- }
2111
- // #region Public Methods
2112
- async upgrade(req, socket, head) {
2113
- const worker = await this.#getWorker();
2114
- if (!worker) {
2115
- throw new HTTPError({
2116
- status: 503,
2117
- statusText: "No worker available."
2118
- });
2119
- }
2120
- return worker.upgrade(req, socket, head);
2121
- }
2122
- listen(opts) {
2123
- const server = serve({
2124
- ...opts,
2125
- fetch: this.fetch
2126
- });
2127
- this.#listeners.push(server);
2128
- if (server.node?.server) {
2129
- server.node.server.on(
2130
- "upgrade",
2131
- (req, sock, head) => this.upgrade(req, sock, head)
2132
- );
2133
- }
2134
- return server;
2135
- }
2136
- async close() {
2137
- await Promise.all(
2138
- [
2139
- Promise.all(this.#listeners.map((l) => l.close())).then(() => {
2140
- this.#listeners = [];
2141
- }),
2142
- Promise.all(this.#workers.map((w) => w.close())).then(() => {
2143
- this.#workers = [];
2144
- }),
2145
- Promise.resolve(this.#watcher?.close()).then(() => {
2146
- this.#watcher = void 0;
2147
- })
2148
- ].map(
2149
- (p) => p.catch((error) => {
2150
- consola.error(error);
2151
- })
2152
- )
2153
- );
2154
- }
2155
- reload() {
2156
- for (const worker2 of this.#workers) {
2157
- worker2.close();
2158
- }
2159
- const worker = new NodeDevWorker({
2160
- name: `Nitro_${this.#workerIdCtr++}`,
2161
- entry: this.#entry,
2162
- data: {
2163
- ...this.#workerData,
2164
- globals: {
2165
- __NITRO_RUNTIME_CONFIG__: this.nitro.options.runtimeConfig,
2166
- ...this.#workerData.globals
2167
- }
2168
- },
2169
- hooks: {
2170
- onClose: (worker2, cause) => {
2171
- this.#workerError = cause;
2172
- const index = this.#workers.indexOf(worker2);
2173
- if (index !== -1) {
2174
- this.#workers.splice(index, 1);
2175
- }
2176
- },
2177
- onReady: (worker2, addr) => {
2178
- this.#writeBuildInfo(worker2, addr);
2179
- }
2180
- }
2181
- });
2182
- if (!worker.closed) {
2183
- for (const listener of this.#messageListeners) {
2184
- worker.onMessage(listener);
2185
- }
2186
- this.#workers.unshift(worker);
2187
- }
2188
- }
2189
- sendMessage(message) {
2190
- for (const worker of this.#workers) {
2191
- if (!worker.closed) {
2192
- worker.sendMessage(message);
2193
- }
2194
- }
2195
- }
2196
- onMessage(listener) {
2197
- this.#messageListeners.add(listener);
2198
- for (const worker of this.#workers) {
2199
- worker.onMessage(listener);
2200
- }
2201
- }
2202
- offMessage(listener) {
2203
- this.#messageListeners.delete(listener);
2204
- for (const worker of this.#workers) {
2205
- worker.offMessage(listener);
2206
- }
2207
- }
2208
- // #endregion
2209
- // #region Private Methods
2210
- #writeBuildInfo(_worker, addr) {
2211
- const buildInfoPath = resolve(this.nitro.options.buildDir, "nitro.json");
2212
- const buildInfo = {
2213
- date: (/* @__PURE__ */ new Date()).toJSON(),
2214
- preset: this.nitro.options.preset,
2215
- framework: this.nitro.options.framework,
2216
- versions: {
2217
- nitro: version
2218
- },
2219
- dev: {
2220
- pid: process.pid,
2221
- workerAddress: addr
2222
- }
2223
- };
2224
- writeFile$1(buildInfoPath, JSON.stringify(buildInfo, null, 2)).catch(
2225
- (error) => {
2226
- consola.error(error);
2227
- }
2228
- );
2229
- }
2230
- async #getWorker() {
2231
- let retry = 0;
2232
- const maxRetries = isTest || isCI ? 100 : 10;
2233
- while (this.#building || ++retry < maxRetries) {
2234
- if ((this.#workers.length === 0 || this.#buildError) && !this.#building) {
2235
- return;
2236
- }
2237
- const activeWorker = this.#workers.find((w) => w.ready);
2238
- if (activeWorker) {
2239
- return activeWorker;
2240
- }
2241
- await new Promise((resolve2) => setTimeout(resolve2, 600));
2242
- }
2243
- }
2244
- #generateError() {
2245
- const error = this.#buildError || this.#workerError;
2246
- if (error) {
2247
- try {
2248
- error.unhandled = false;
2249
- let id = error.id || error.path;
2250
- if (id) {
2251
- const cause = error.errors?.[0];
2252
- const loc = error.location || error.loc || cause?.location || cause?.loc;
2253
- if (loc) {
2254
- id += `:${loc.line}:${loc.column}`;
2255
- }
2256
- error.stack = (error.stack || "").replace(
2257
- /(^\s*at\s+.+)/m,
2258
- ` at ${id}
2259
- $1`
2260
- );
2261
- }
2262
- } catch {
2263
- }
2264
- return new HTTPError(error);
2265
- }
2266
- return new Response(
2267
- JSON.stringify(
2268
- {
2269
- error: "Dev server is unavailable.",
2270
- hint: "Please reload the page and check the console for errors if the issue persists."
2271
- },
2272
- null,
2273
- 2
2274
- ),
2275
- {
2276
- status: 503,
2277
- statusText: "Dev server is unavailable",
2278
- headers: {
2279
- "Content-Type": "application/json",
2280
- "Cache-Control": "no-store",
2281
- Refresh: "3"
2282
- }
2283
- }
2284
- );
2285
- }
2286
- // #endregion
2287
- }
42
+ import { c as createProxyServer } from '../_chunks/_deps/httpxy.mjs';
43
+ import { a as assetsPlugin } from '../_chunks/_deps/@pi0/vite-plugin-fullstack.mjs';
2288
44
 
2289
45
  const getViteRollupConfig = (ctx) => {
2290
46
  const nitro = ctx.nitro;
@@ -2413,7 +169,7 @@ function virtualBundlePlugin(bundles) {
2413
169
  return resolve(id);
2414
170
  }
2415
171
  if (importer) {
2416
- const resolved = resolve(dirname$1(importer), id);
172
+ const resolved = resolve(dirname(importer), id);
2417
173
  if (modules.has(resolved)) {
2418
174
  return resolved;
2419
175
  }
@@ -2448,7 +204,7 @@ async function buildEnvironments(ctx, builder) {
2448
204
  }
2449
205
  continue;
2450
206
  }
2451
- if (!isTest && !isCI) console.log();
207
+ if (!a && !T) console.log();
2452
208
  nitro.logger.start(`Building [${fmtName}]`);
2453
209
  await builder.build(env);
2454
210
  }
@@ -2468,13 +224,13 @@ async function buildEnvironments(ctx, builder) {
2468
224
  );
2469
225
  await rm(outputPath);
2470
226
  const tmp = resolve(nitroOptions.buildDir, "vite/index.html");
2471
- await mkdir(dirname$1(tmp), { recursive: true });
2472
- await writeFile$1(tmp, html, "utf8");
227
+ await mkdir(dirname(tmp), { recursive: true });
228
+ await writeFile(tmp, html, "utf8");
2473
229
  nitroOptions.renderer.template = tmp;
2474
230
  }
2475
231
  }
2476
232
  await builder.writeAssetsManifest?.();
2477
- if (!isTest && !isCI) console.log();
233
+ if (!a && !T) console.log();
2478
234
  const buildInfo = [
2479
235
  ["preset", nitro.options.preset],
2480
236
  ["compatibility", formatCompatibilityDate(nitro.options.compatibilityDate)]
@@ -2491,7 +247,7 @@ async function buildEnvironments(ctx, builder) {
2491
247
  const rewriteRelativePaths = (input) => {
2492
248
  return input.replace(/([\s:])\.\/(\S*)/g, `$1${rOutput}/$2`);
2493
249
  };
2494
- if (!isTest && !isCI) console.log();
250
+ if (!a && !T) console.log();
2495
251
  if (nitro.options.commands.preview) {
2496
252
  nitro.logger.success(
2497
253
  `You can preview this build using \`${rewriteRelativePaths(
@@ -3243,24 +999,4 @@ function getEntry(input) {
3243
999
  }
3244
1000
  }
3245
1001
 
3246
- async function viteBuild(nitro$1) {
3247
- if (nitro$1.options.dev) {
3248
- throw new Error(
3249
- "Nitro vite builder is not supported in development mode. Please use `vite dev` instead."
3250
- );
3251
- }
3252
- const { createBuilder } = await import('vite');
3253
- const builder = await createBuilder({
3254
- base: nitro$1.options.rootDir,
3255
- plugins: [await nitro({ _nitro: nitro$1 })],
3256
- logLevel: isTest ? "warn" : void 0
3257
- });
3258
- await builder.buildApp();
3259
- }
3260
-
3261
- const build = {
3262
- __proto__: null,
3263
- viteBuild: viteBuild
3264
- };
3265
-
3266
- export { NitroDevServer as N, createDevServer as a, listTasks as b, createNitro as c, build as d, loadOptions as l, nitro as n, prerender as p, runTask as r };
1002
+ export { nitro as n };