nitro-nightly 4.0.0-20251010-091516-7cafddba → 4.0.0-20251030-091344-d4418b98

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 (195) hide show
  1. package/dist/{_chunks/build2.mjs → _build/build.mjs} +108 -58
  2. package/dist/_build/build2.mjs +556 -0
  3. package/dist/_build/info.mjs +1002 -0
  4. package/dist/_build/prepare.mjs +1511 -0
  5. package/dist/_build/snapshot.mjs +185 -0
  6. package/dist/{_chunks/plugin.mjs → _build/vite.mjs} +295 -296
  7. package/dist/_build/vite2.mjs +149 -0
  8. package/dist/_chunks/_deps/@jridgewell/gen-mapping.mjs +189 -0
  9. package/dist/_chunks/_deps/@jridgewell/remapping.mjs +137 -0
  10. package/dist/_chunks/_deps/@jridgewell/resolve-uri.mjs +231 -0
  11. package/dist/_chunks/_deps/@jridgewell/sourcemap-codec.mjs +173 -0
  12. package/dist/_chunks/_deps/@jridgewell/trace-mapping.mjs +170 -0
  13. package/dist/_chunks/_deps/@pi0/vite-plugin-fullstack.mjs +575 -0
  14. package/dist/_chunks/_deps/@rollup/plugin-alias.mjs +89 -0
  15. package/dist/_chunks/_deps/@rollup/plugin-commonjs.mjs +2376 -0
  16. package/dist/_chunks/{index2.mjs → _deps/@rollup/plugin-inject.mjs} +5 -90
  17. package/dist/_chunks/_deps/@rollup/plugin-json.mjs +37 -0
  18. package/dist/_chunks/_deps/@rollup/plugin-node-resolve.mjs +1386 -0
  19. package/dist/_chunks/_deps/@rollup/plugin-replace.mjs +133 -0
  20. package/dist/_chunks/_deps/@rollup/pluginutils.mjs +346 -0
  21. package/dist/_chunks/_deps/acorn.mjs +6225 -0
  22. package/dist/_chunks/_deps/c12.mjs +510 -0
  23. package/dist/_chunks/_deps/chokidar.mjs +1428 -0
  24. package/dist/_chunks/_deps/citty.mjs +460 -0
  25. package/dist/_chunks/_deps/commondir.mjs +77 -0
  26. package/dist/_chunks/_deps/compatx.mjs +76 -0
  27. package/dist/_chunks/_deps/confbox.mjs +300 -0
  28. package/dist/_chunks/_deps/debug.mjs +885 -0
  29. package/dist/_chunks/_deps/deepmerge.mjs +147 -0
  30. package/dist/_chunks/_deps/depd.mjs +550 -0
  31. package/dist/_chunks/_deps/dot-prop.mjs +282 -0
  32. package/dist/_chunks/_deps/dotenv.mjs +555 -0
  33. package/dist/_chunks/_deps/duplexer.mjs +1 -0
  34. package/dist/_chunks/_deps/ee-first.mjs +104 -0
  35. package/dist/_chunks/_deps/encodeurl.mjs +69 -0
  36. package/dist/_chunks/_deps/escape-html.mjs +87 -0
  37. package/dist/_chunks/_deps/escape-string-regexp.mjs +13 -0
  38. package/dist/_chunks/_deps/estree-walker.mjs +433 -0
  39. package/dist/_chunks/_deps/etag.mjs +147 -0
  40. package/dist/_chunks/_deps/exsolve.mjs +1416 -0
  41. package/dist/_chunks/_deps/fdir.mjs +569 -0
  42. package/dist/_chunks/_deps/fresh.mjs +145 -0
  43. package/dist/_chunks/_deps/function-bind.mjs +106 -0
  44. package/dist/_chunks/{index4.mjs → _deps/giget.mjs} +21 -776
  45. package/dist/_chunks/_deps/gzip-size.mjs +19 -0
  46. package/dist/_chunks/_deps/hasown.mjs +19 -0
  47. package/dist/_chunks/_deps/http-errors.mjs +307 -0
  48. package/dist/_chunks/_deps/httpxy.mjs +580 -0
  49. package/dist/_chunks/_deps/inherits.mjs +57 -0
  50. package/dist/_chunks/_deps/is-core-module.mjs +596 -0
  51. package/dist/_chunks/_deps/is-module.mjs +25 -0
  52. package/dist/_chunks/_deps/is-reference.mjs +31 -0
  53. package/dist/_chunks/_deps/js-tokens.mjs +411 -0
  54. package/dist/_chunks/_deps/klona.mjs +137 -0
  55. package/dist/_chunks/_deps/knitwork.mjs +172 -0
  56. package/dist/_chunks/_deps/local-pkg.mjs +163 -0
  57. package/dist/_chunks/_deps/magic-string.mjs +1296 -0
  58. package/dist/_chunks/_deps/mime-db.mjs +11685 -0
  59. package/dist/_chunks/_deps/mime-types.mjs +287 -0
  60. package/dist/_chunks/_deps/mime.mjs +1172 -0
  61. package/dist/_chunks/_deps/mlly.mjs +2413 -0
  62. package/dist/_chunks/_deps/ms.mjs +172 -0
  63. package/dist/_chunks/_deps/node-fetch-native.mjs +3 -0
  64. package/dist/_chunks/_deps/nypm.mjs +219 -0
  65. package/dist/_chunks/_deps/on-finished.mjs +246 -0
  66. package/dist/_chunks/_deps/parseurl.mjs +168 -0
  67. package/dist/_chunks/_deps/path-parse.mjs +85 -0
  68. package/dist/_chunks/{pathe.M-eThtNZ.mjs → _deps/pathe.mjs} +48 -1
  69. package/dist/_chunks/_deps/perfect-debounce.mjs +88 -0
  70. package/dist/_chunks/_deps/picomatch.mjs +2144 -0
  71. package/dist/_chunks/_deps/pkg-types.mjs +247 -0
  72. package/dist/_chunks/{snapshot.mjs → _deps/pretty-bytes.mjs} +1 -105
  73. package/dist/_chunks/_deps/quansync.mjs +99 -0
  74. package/dist/_chunks/_deps/range-parser.mjs +171 -0
  75. package/dist/_chunks/_deps/rc9.mjs +219 -0
  76. package/dist/_chunks/_deps/readdirp.mjs +245 -0
  77. package/dist/_chunks/_deps/resolve.mjs +1260 -0
  78. package/dist/_chunks/_deps/rou3.mjs +326 -0
  79. package/dist/_chunks/_deps/send.mjs +1022 -0
  80. package/dist/_chunks/_deps/serve-static.mjs +228 -0
  81. package/dist/_chunks/_deps/setprototypeof.mjs +26 -0
  82. package/dist/_chunks/_deps/statuses.mjs +457 -0
  83. package/dist/_chunks/_deps/std-env.mjs +3 -0
  84. package/dist/_chunks/_deps/strip-literal.mjs +67 -0
  85. package/dist/_chunks/_deps/supports-color.mjs +44 -0
  86. package/dist/_chunks/_deps/tinyexec.mjs +552 -0
  87. package/dist/_chunks/_deps/tinyglobby.mjs +293 -0
  88. package/dist/_chunks/_deps/toidentifier.mjs +41 -0
  89. package/dist/_chunks/_deps/ultrahtml.mjs +3 -0
  90. package/dist/_chunks/_deps/unimport.mjs +2267 -0
  91. package/dist/_chunks/_deps/unplugin-utils.mjs +65 -0
  92. package/dist/_chunks/_deps/unplugin.mjs +1294 -0
  93. package/dist/_chunks/_deps/untyped.mjs +375 -0
  94. package/dist/_chunks/{info.mjs → _deps/unwasm.mjs} +8 -4206
  95. package/dist/_chunks/_deps/webpack-virtual-modules.mjs +360 -0
  96. package/dist/_chunks/_presets/_all.mjs +59 -0
  97. package/dist/_chunks/_presets/_nitro.mjs +74 -0
  98. package/dist/_chunks/_presets/_resolve.mjs +64 -0
  99. package/dist/_chunks/_presets/_static.mjs +69 -0
  100. package/dist/_chunks/_presets/_types.mjs +3 -0
  101. package/dist/_chunks/_presets/_utils.mjs +31 -0
  102. package/dist/_chunks/_presets/alwaysdata.mjs +17 -0
  103. package/dist/_chunks/_presets/aws-amplify.mjs +111 -0
  104. package/dist/_chunks/_presets/aws-lambda.mjs +23 -0
  105. package/dist/_chunks/_presets/azure.mjs +162 -0
  106. package/dist/_chunks/_presets/bun.mjs +19 -0
  107. package/dist/_chunks/_presets/cleavr.mjs +15 -0
  108. package/dist/_chunks/_presets/cloudflare.mjs +608 -0
  109. package/dist/_chunks/_presets/deno.mjs +196 -0
  110. package/dist/_chunks/_presets/digitalocean.mjs +14 -0
  111. package/dist/_chunks/_presets/firebase.mjs +47 -0
  112. package/dist/_chunks/_presets/flightcontrol.mjs +14 -0
  113. package/dist/_chunks/_presets/genezio.mjs +13 -0
  114. package/dist/_chunks/_presets/heroku.mjs +14 -0
  115. package/dist/_chunks/_presets/iis.mjs +194 -0
  116. package/dist/_chunks/_presets/index.mjs +62 -0
  117. package/dist/_chunks/_presets/koyeb.mjs +14 -0
  118. package/dist/_chunks/_presets/netlify.mjs +241 -0
  119. package/dist/_chunks/_presets/node.mjs +54 -0
  120. package/dist/_chunks/_presets/platform.mjs +14 -0
  121. package/dist/_chunks/_presets/render.mjs +14 -0
  122. package/dist/_chunks/_presets/standard.mjs +23 -0
  123. package/dist/_chunks/_presets/stormkit.mjs +18 -0
  124. package/dist/_chunks/_presets/vercel.mjs +375 -0
  125. package/dist/_chunks/_presets/winterjs.mjs +22 -0
  126. package/dist/_chunks/_presets/zeabur.mjs +69 -0
  127. package/dist/_chunks/_presets/zerops.mjs +27 -0
  128. package/dist/_chunks/app.mjs +9 -19206
  129. package/dist/_chunks/{index3.mjs → builder.mjs} +560 -970
  130. package/dist/_chunks/server.mjs +6 -4
  131. package/dist/{cli → _cli}/build.mjs +3 -8
  132. package/dist/{cli → _cli}/dev.mjs +38 -12
  133. package/dist/{cli/index2.mjs → _cli/index.mjs} +1 -2
  134. package/dist/{cli → _cli}/list.mjs +3 -4
  135. package/dist/{cli → _cli}/prepare.mjs +3 -4
  136. package/dist/{cli → _cli}/run.mjs +3 -4
  137. package/dist/{index.d.mts → builder.d.mts} +11 -11
  138. package/dist/builder.mjs +117 -0
  139. package/dist/cli/index.mjs +7 -464
  140. package/dist/node_modules/@speed-highlight/core/dist/index.js +1 -1
  141. package/dist/node_modules/@speed-highlight/core/dist/terminal.js +1 -1
  142. package/dist/node_modules/@speed-highlight/core/package.json +7 -3
  143. package/dist/node_modules/cookie-es/dist/index.mjs +262 -0
  144. package/dist/node_modules/cookie-es/package.json +37 -0
  145. package/dist/node_modules/hookable/dist/index.mjs +243 -266
  146. package/dist/node_modules/hookable/package.json +29 -26
  147. package/dist/node_modules/rendu/dist/index.mjs +380 -0
  148. package/dist/node_modules/rendu/package.json +47 -0
  149. package/dist/presets/_nitro/runtime/nitro-dev.mjs +4 -7
  150. package/dist/presets/_nitro/runtime/nitro-prerenderer.mjs +5 -4
  151. package/dist/presets/azure/runtime/azure-swa.mjs +1 -1
  152. package/dist/presets/cloudflare/runtime/_module-handler.mjs +7 -6
  153. package/dist/presets/cloudflare/runtime/cloudflare-durable.mjs +4 -5
  154. package/dist/presets/cloudflare/runtime/plugin.dev.mjs +7 -10
  155. package/dist/presets/cloudflare/runtime/shims/workers.dev.d.mts +21 -0
  156. package/dist/presets/cloudflare/runtime/shims/workers.dev.mjs +27 -0
  157. package/dist/presets/node/runtime/node-server.mjs +1 -1
  158. package/dist/runtime/index.d.mts +1 -1
  159. package/dist/runtime/index.mjs +1 -1
  160. package/dist/runtime/internal/app.d.mts +3 -1
  161. package/dist/runtime/internal/app.mjs +90 -64
  162. package/dist/runtime/internal/error/prod.d.mts +3 -2
  163. package/dist/runtime/internal/error/prod.mjs +9 -13
  164. package/dist/runtime/internal/renderer.mjs +4 -4
  165. package/dist/runtime/internal/routes/dev-tasks.d.mts +30 -2
  166. package/dist/runtime/internal/shutdown.d.mts +1 -2
  167. package/dist/runtime/internal/shutdown.mjs +3 -2
  168. package/dist/runtime/internal/task.mjs +1 -2
  169. package/dist/types/index.d.mts +1603 -10
  170. package/dist/vite.d.mts +5 -0
  171. package/dist/vite.mjs +94 -30
  172. package/lib/index.mjs +1 -0
  173. package/lib/indexd.mts +1 -0
  174. package/lib/runtime/meta.mjs +35 -0
  175. package/package.json +40 -41
  176. package/dist/_chunks/build.mjs +0 -84
  177. package/dist/_chunks/build3.mjs +0 -6452
  178. package/dist/_chunks/detect-acorn.mjs +0 -503
  179. package/dist/_chunks/index.mjs +0 -22242
  180. package/dist/_chunks/json5.mjs +0 -68
  181. package/dist/_chunks/jsonc.mjs +0 -51
  182. package/dist/_chunks/toml.mjs +0 -259
  183. package/dist/_chunks/yaml.mjs +0 -86
  184. package/dist/index.mjs +0 -55
  185. package/dist/node_modules/klona/dist/index.mjs +0 -81
  186. package/dist/node_modules/klona/full/index.mjs +0 -53
  187. package/dist/node_modules/klona/package.json +0 -74
  188. package/dist/node_modules/std-env/dist/index.mjs +0 -1
  189. package/dist/node_modules/std-env/package.json +0 -46
  190. package/dist/presets.mjs +0 -2460
  191. package/dist/runtime/internal/debug.d.mts +0 -2
  192. package/dist/runtime/internal/debug.mjs +0 -5
  193. package/lib/runtime-meta.mjs +0 -38
  194. /package/dist/{cli → _cli}/common.mjs +0 -0
  195. /package/lib/{runtime-meta.d.mts → runtime/meta.d.mts} +0 -0
@@ -1,26 +1,32 @@
1
- import { i as createNitro, k as addRoute, l as scanUnprefixedPublicAssets, m as compressPublicAssets, n as mime, w as writeFile, o as findAllRoutes, q as createRouter, t as genObjectKey, u as resolveNitroPath, v as toExports, r as resolveModulePath, x as parseNodeModulePath, y as lookupNodeModuleSubpath, z as isDirectory } from './index.mjs';
1
+ import { r as resolveNitroPath, i as isDirectory, w as writeFile, c as createNitro, b as scanUnprefixedPublicAssets, d as compressPublicAssets } from '../_build/prepare.mjs';
2
+ import { existsSync, promises } from 'node:fs';
3
+ import { defu } from 'defu';
4
+ import { i as parseNodeModulePath, l as lookupNodeModuleSubpath } from './_deps/mlly.mjs';
5
+ import { r as resolveModulePath } from './_deps/exsolve.mjs';
6
+ import { runtimeDir } from 'nitro/runtime/meta';
7
+ import { r as resolve, a as relative, c as resolveAlias, i as isAbsolute, j as join, d as dirname } from './_deps/pathe.mjs';
8
+ import { g as generateTypes, r as resolveSchema } from './_deps/untyped.mjs';
9
+ import { t as toExports } from './_deps/unimport.mjs';
10
+ import './server.mjs';
2
11
  import { pathToFileURL } from 'node:url';
3
12
  import { colors } from 'consola/utils';
4
- import { defu } from 'defu';
13
+ import { m as mime } from './_deps/mime.mjs';
14
+ import { a as addRoute, f as findAllRoutes, c as createRouter } from './_deps/rou3.mjs';
5
15
  import { parseURL, withTrailingSlash, withBase, joinURL, withoutBase } from 'ufo';
6
- import { a as relative, r as resolve, j as join, c as normalizeWindowsPath, i as isAbsolute, d as dirname } from './pathe.M-eThtNZ.mjs';
7
- import './server.mjs';
8
- import { existsSync, promises } from 'node:fs';
9
- import { runtimeDir } from 'nitro/runtime/meta';
10
- import 'scule';
16
+ import { z, P } from './_deps/ultrahtml.mjs';
11
17
 
12
18
  async function build(nitro) {
13
19
  switch (nitro.options.builder) {
14
20
  case "rollup": {
15
- const { rollupBuild } = await import('./build3.mjs');
21
+ const { rollupBuild } = await import('../_build/build2.mjs');
16
22
  return rollupBuild(nitro);
17
23
  }
18
24
  case "rolldown": {
19
- const { rolldownBuild } = await import('./build2.mjs');
25
+ const { rolldownBuild } = await import('../_build/build.mjs');
20
26
  return rolldownBuild(nitro);
21
27
  }
22
28
  case "vite": {
23
- const { viteBuild } = await import('./build.mjs');
29
+ const { viteBuild } = await import('../_build/vite2.mjs');
24
30
  return viteBuild(nitro);
25
31
  }
26
32
  default: {
@@ -29,1030 +35,614 @@ async function build(nitro) {
29
35
  }
30
36
  }
31
37
 
32
- async function runParallel(inputs, cb, opts) {
33
- const tasks = /* @__PURE__ */ new Set();
34
- function queueNext() {
35
- const route = inputs.values().next().value;
36
- if (!route) {
37
- return;
38
- }
39
- inputs.delete(route);
40
- const task = (opts.interval ? new Promise((resolve) => setTimeout(resolve, opts.interval)) : Promise.resolve()).then(() => cb(route)).catch((error) => {
41
- console.error(error);
42
- });
43
- tasks.add(task);
44
- return task.then(() => {
45
- tasks.delete(task);
46
- if (inputs.size > 0) {
47
- return refillQueue();
48
- }
49
- });
50
- }
51
- function refillQueue() {
52
- const workers = Math.min(opts.concurrency - tasks.size, inputs.size);
53
- return Promise.all(Array.from({ length: workers }, () => queueNext()));
54
- }
55
- await refillQueue();
56
- }
57
-
58
- var D=new Set(["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),x=new Set(["script","style"]),o=/(?:<(\/?)([a-zA-Z][a-zA-Z0-9\:-]*)(?:\s([^>]*?))?((?:\s*\/)?)>|(<\!\-\-)([\s\S]*?)(\-\->)|(<\!)([\s\S]*?)(>))/gm,b=/[\@\.a-z0-9_\:\-]/i;function I(e){let t={};if(e){let i="none",r,n="",a,l;for(let c=0;c<e.length;c++){let d=e[c];i==="none"?b.test(d)?(r&&(t[r]=n,r=void 0,n=""),a=c,i="key"):d==="="&&r&&(i="value"):i==="key"?b.test(d)||(r=e.substring(a,c),d==="="?i="value":i="none"):d===l&&c>0&&e[c-1]!=="\\"?l&&(n=e.substring(a,c),l=void 0,i="none"):(d==='"'||d==="'")&&!l&&(a=c+1,l=d);}i==="key"&&a!=null&&a<e.length&&(r=e.substring(a,e.length)),r&&(t[r]=n);}return t}function P(e){let t=typeof e=="string"?e:e.value,i,r,n,a,l,c,d,m,s,u=[];o.lastIndex=0,r=i={type:0,children:[]};let g=0;function h(){a=t.substring(g,o.lastIndex-n[0].length),a&&r.children.push({type:2,value:a,parent:r});}for(;n=o.exec(t);){if(c=n[5]||n[8],d=n[6]||n[9],m=n[7]||n[10],x.has(r.name)&&n[2]!==r.name){l=o.lastIndex-n[0].length,r.children.length>0&&(r.children[0].value+=n[0]);continue}else if(c==="<!--"){if(l=o.lastIndex-n[0].length,x.has(r.name))continue;s={type:3,value:d,parent:r,loc:[{start:l,end:l+c.length},{start:o.lastIndex-m.length,end:o.lastIndex}]},u.push(s),s.parent.children.push(s);}else if(c==="<!")l=o.lastIndex-n[0].length,s={type:4,value:d,parent:r,loc:[{start:l,end:l+c.length},{start:o.lastIndex-m.length,end:o.lastIndex}]},u.push(s),s.parent.children.push(s);else if(n[1]!=="/")if(h(),x.has(r.name)){g=o.lastIndex,h();continue}else s={type:1,name:n[2]+"",attributes:I(n[3]),parent:r,children:[],loc:[{start:o.lastIndex-n[0].length,end:o.lastIndex}]},u.push(s),s.parent.children.push(s),n[4]&&n[4].indexOf("/")>-1||D.has(s.name)?(s.loc[1]=s.loc[0],s.isSelfClosingTag=true):r=s;else h(),n[2]+""===r.name?(s=r,r=s.parent,s.loc.push({start:o.lastIndex-n[0].length,end:o.lastIndex}),a=t.substring(s.loc[0].end,s.loc[1].start),s.children.length===0&&s.children.push({type:2,value:a,parent:r})):n[2]+""===u[u.length-1].name&&u[u.length-1].isSelfClosingTag===true&&(s=u[u.length-1],s.loc.push({start:o.lastIndex-n[0].length,end:o.lastIndex}));g=o.lastIndex;}return a=t.slice(g),r.children.push({type:2,value:a,parent:r}),i}var T=class{constructor(t){this.callback=t;}async visit(t,i,r){if(await this.callback(t,i,r),Array.isArray(t.children)){let n=[];for(let a=0;a<t.children.length;a++){let l=t.children[a];n.push(this.visit(l,t,a));}await Promise.all(n);}}};function z(e,t){return new T(t).visit(e)}
59
-
60
- const allowedExtensions = /* @__PURE__ */ new Set(["", ".json"]);
61
- const linkParents$1 = /* @__PURE__ */ new Map();
62
- const HTML_ENTITIES = {
63
- "&lt;": "<",
64
- "&gt;": ">",
65
- "&amp;": "&",
66
- "&apos;": "'",
67
- "&quot;": '"'
68
- };
69
- function escapeHtml(text) {
70
- return text.replace(
71
- /&(lt|gt|amp|apos|quot);/g,
72
- (ch) => HTML_ENTITIES[ch] || ch
73
- );
74
- }
75
- async function extractLinks(html, from, res, crawlLinks) {
76
- const links = [];
77
- const _links = [];
78
- if (crawlLinks) {
79
- await z(P(html), (node) => {
80
- if (!node.attributes?.href) {
81
- return;
82
- }
83
- const link = escapeHtml(node.attributes.href);
84
- if (!decodeURIComponent(link).startsWith("#") && allowedExtensions.has(getExtension(link))) {
85
- _links.push(link);
86
- }
87
- });
88
- }
89
- const header = res.headers.get("x-nitro-prerender") || "";
90
- _links.push(...header.split(",").map((i) => decodeURIComponent(i.trim())));
91
- for (const link of _links.filter(Boolean)) {
92
- const _link = parseURL(link);
93
- if (_link.protocol || _link.host) {
38
+ async function writeTypes(nitro) {
39
+ const types = {
40
+ routes: {}
41
+ };
42
+ const typesDir = resolve(nitro.options.buildDir, "types");
43
+ const middleware = [...nitro.scannedHandlers, ...nitro.options.handlers];
44
+ for (const mw of middleware) {
45
+ if (typeof mw.handler !== "string" || !mw.route) {
94
46
  continue;
95
47
  }
96
- if (!_link.pathname.startsWith("/")) {
97
- const fromURL = new URL(from, "http://localhost");
98
- _link.pathname = new URL(_link.pathname, fromURL).pathname;
99
- }
100
- links.push(_link.pathname + _link.search);
101
- }
102
- for (const link of links) {
103
- const _parents = linkParents$1.get(link);
104
- if (_parents) {
105
- _parents.add(from);
106
- } else {
107
- linkParents$1.set(link, /* @__PURE__ */ new Set([from]));
108
- }
109
- }
110
- return links;
111
- }
112
- const EXT_REGEX = /\.[\da-z]+$/;
113
- function getExtension(link) {
114
- const pathname = parseURL(link).pathname;
115
- return (pathname.match(EXT_REGEX) || [])[0] || "";
116
- }
117
- function formatPrerenderRoute(route) {
118
- let str = ` \u251C\u2500 ${route.route} (${route.generateTimeMS}ms)`;
119
- if (route.error) {
120
- const parents = linkParents$1.get(route.route);
121
- const errorColor = colors[route.error.status === 404 ? "yellow" : "red"];
122
- const errorLead = parents?.size ? "\u251C\u2500\u2500" : "\u2514\u2500\u2500";
123
- str += `
124
- \u2502 ${errorLead} ${errorColor(route.error.message)}`;
125
- if (parents?.size) {
126
- str += `
127
- ${[...parents.values()].map((link) => ` \u2502 \u2514\u2500\u2500 Linked from ${link}`).join("\n")}`;
128
- }
129
- }
130
- if (route.skip) {
131
- str += colors.gray(" (skipped)");
132
- }
133
- return colors.gray(str);
134
- }
135
- function matchesIgnorePattern(path, pattern) {
136
- if (typeof pattern === "string") {
137
- return path.startsWith(pattern);
138
- }
139
- if (typeof pattern === "function") {
140
- return pattern(path) === true;
141
- }
142
- if (pattern instanceof RegExp) {
143
- return pattern.test(path);
144
- }
145
- return false;
146
- }
147
-
148
- const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
149
- const linkParents = /* @__PURE__ */ new Map();
150
- async function prerender(nitro) {
151
- if (nitro.options.noPublicDir) {
152
- nitro.logger.warn(
153
- "Skipping prerender since `noPublicDir` option is enabled."
48
+ const relativePath = relative(
49
+ typesDir,
50
+ resolveNitroPath(mw.handler, nitro.options)
51
+ ).replace(/\.(js|mjs|cjs|ts|mts|cts|tsx|jsx)$/, "");
52
+ const method = mw.method || "default";
53
+ types.routes[mw.route] ??= {};
54
+ types.routes[mw.route][method] ??= [];
55
+ types.routes[mw.route][method].push(
56
+ `Simplify<Serialize<Awaited<ReturnType<typeof import('${relativePath}').default>>>>`
154
57
  );
155
- return;
156
58
  }
157
- if (nitro.options.builder === "vite") {
158
- nitro.logger.warn(
159
- "Skipping prerender since not supported with vite builder yet..."
59
+ let autoImportedTypes = [];
60
+ let autoImportExports = "";
61
+ if (nitro.unimport) {
62
+ await nitro.unimport.init();
63
+ const allImports = await nitro.unimport.getImports();
64
+ autoImportExports = toExports(allImports).replace(
65
+ /#internal\/nitro/g,
66
+ relative(typesDir, runtimeDir)
160
67
  );
161
- return;
162
- }
163
- const routes = new Set(nitro.options.prerender.routes);
164
- const prerenderRulePaths = Object.entries(nitro.options.routeRules).filter(([path2, options]) => options.prerender && !path2.includes("*")).map((e) => e[0]);
165
- for (const route of prerenderRulePaths) {
166
- routes.add(route);
167
- }
168
- await nitro.hooks.callHook("prerender:routes", routes);
169
- if (routes.size === 0) {
170
- if (nitro.options.prerender.crawlLinks) {
171
- routes.add("/");
172
- } else {
173
- return;
174
- }
175
- }
176
- nitro.logger.info("Initializing prerenderer");
177
- nitro._prerenderedRoutes = [];
178
- nitro._prerenderMeta = nitro._prerenderMeta || {};
179
- const prerendererConfig = {
180
- ...nitro.options._config,
181
- static: false,
182
- rootDir: nitro.options.rootDir,
183
- logLevel: 0,
184
- preset: "nitro-prerender"
185
- };
186
- await nitro.hooks.callHook("prerender:config", prerendererConfig);
187
- const nitroRenderer = await createNitro(prerendererConfig);
188
- const prerenderStartTime = Date.now();
189
- await nitro.hooks.callHook("prerender:init", nitroRenderer);
190
- let path = relative(nitro.options.output.dir, nitro.options.output.publicDir);
191
- if (!path.startsWith(".")) {
192
- path = `./${path}`;
193
- }
194
- nitroRenderer.options.commands.preview = `npx serve ${path}`;
195
- nitroRenderer.options.output.dir = nitro.options.output.dir;
196
- await build(nitroRenderer);
197
- const serverFilename = typeof nitroRenderer.options.rollupConfig?.output?.entryFileNames === "string" ? nitroRenderer.options.rollupConfig.output.entryFileNames : "index.mjs";
198
- const serverEntrypoint = resolve(
199
- nitroRenderer.options.output.serverDir,
200
- serverFilename
201
- );
202
- const { closePrerenderer, appFetch } = await import(pathToFileURL(serverEntrypoint).href);
203
- const routeRules = createRouter();
204
- for (const [route, rules] of Object.entries(nitro.options.routeRules)) {
205
- addRoute(routeRules, void 0, route, rules);
206
- }
207
- const _getRouteRules = (path2) => defu(
208
- {},
209
- ...findAllRoutes(routeRules, void 0, path2).map((r) => r.data).reverse()
210
- );
211
- const generatedRoutes = /* @__PURE__ */ new Set();
212
- const failedRoutes = /* @__PURE__ */ new Set();
213
- const skippedRoutes = /* @__PURE__ */ new Set();
214
- const displayedLengthWarns = /* @__PURE__ */ new Set();
215
- const publicAssetBases = nitro.options.publicAssets.filter(
216
- (a) => !!a.baseURL && a.baseURL !== "/" && !a.fallthrough
217
- ).map((a) => withTrailingSlash(a.baseURL));
218
- const scannedPublicAssets = nitro.options.prerender.ignoreUnprefixedPublicAssets ? new Set(await scanUnprefixedPublicAssets(nitro)) : /* @__PURE__ */ new Set();
219
- const canPrerender = (route = "/") => {
220
- if (generatedRoutes.has(route) || skippedRoutes.has(route)) {
221
- return false;
222
- }
223
- for (const pattern of nitro.options.prerender.ignore) {
224
- if (matchesIgnorePattern(route, pattern)) {
225
- return false;
68
+ const resolvedImportPathMap = /* @__PURE__ */ new Map();
69
+ for (const i of allImports) {
70
+ const from = i.typeFrom || i.from;
71
+ if (resolvedImportPathMap.has(from)) {
72
+ continue;
226
73
  }
74
+ let path = resolveAlias(from, nitro.options.alias);
75
+ if (!isAbsolute(path)) {
76
+ const resolvedPath = resolveModulePath(from, {
77
+ try: true,
78
+ from: nitro.options.nodeModulesDirs,
79
+ conditions: ["type", "node", "import"],
80
+ suffixes: ["", "/index"],
81
+ extensions: [".mjs", ".cjs", ".js", ".mts", ".cts", ".ts"]
82
+ });
83
+ if (resolvedPath) {
84
+ const { dir, name } = parseNodeModulePath(resolvedPath);
85
+ if (!dir || !name) {
86
+ path = resolvedPath;
87
+ } else {
88
+ const subpath = await lookupNodeModuleSubpath(resolvedPath);
89
+ path = join(dir, name, subpath || "");
90
+ }
91
+ }
92
+ }
93
+ if (existsSync(path) && !await isDirectory(path)) {
94
+ path = path.replace(/\.[a-z]+$/, "");
95
+ }
96
+ if (isAbsolute(path)) {
97
+ path = relative(typesDir, path);
98
+ }
99
+ resolvedImportPathMap.set(from, path);
227
100
  }
228
- if (publicAssetBases.some((base) => route.startsWith(base))) {
229
- return false;
230
- }
231
- if (scannedPublicAssets.has(route)) {
232
- return false;
233
- }
234
- if (_getRouteRules(route).prerender === false) {
235
- return false;
236
- }
237
- return true;
238
- };
239
- const canWriteToDisk = (route) => {
240
- if (route.route.includes("?")) {
241
- return false;
242
- }
243
- const FS_MAX_SEGMENT = 255;
244
- const FS_MAX_PATH = 1024;
245
- const FS_MAX_PATH_PUBLIC_HTML = FS_MAX_PATH - (nitro.options.output.publicDir.length + 10);
246
- if ((route.route.length >= FS_MAX_PATH_PUBLIC_HTML || route.route.split("/").some((s) => s.length > FS_MAX_SEGMENT)) && !displayedLengthWarns.has(route)) {
247
- displayedLengthWarns.add(route);
248
- const _route = route.route.slice(0, 60) + "...";
249
- if (route.route.length >= FS_MAX_PATH_PUBLIC_HTML) {
250
- nitro.logger.warn(
251
- `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}\`.`
252
- );
253
- } else {
254
- nitro.logger.warn(
255
- `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.`
256
- );
257
- return false;
258
- }
259
- }
260
- return true;
261
- };
262
- const generateRoute = async (route) => {
263
- const start = Date.now();
264
- route = decodeURI(route);
265
- if (!canPrerender(route)) {
266
- skippedRoutes.add(route);
267
- return;
268
- }
269
- generatedRoutes.add(route);
270
- const _route = { route };
271
- const encodedRoute = encodeURI(route);
272
- const res = await appFetch(withBase(encodedRoute, nitro.options.baseURL), {
273
- headers: [["x-nitro-prerender", encodedRoute]]
274
- // TODO
275
- // retry: nitro.options.prerender.retry,
276
- // retryDelay: nitro.options.prerender.retryDelay,
277
- });
278
- let dataBuff = Buffer.from(await res.arrayBuffer());
279
- Object.defineProperty(_route, "contents", {
280
- get: () => {
281
- return dataBuff ? dataBuff.toString("utf8") : void 0;
282
- },
283
- set(value) {
284
- if (dataBuff) {
285
- dataBuff = Buffer.from(value);
101
+ autoImportedTypes = [
102
+ nitro.options.imports && nitro.options.imports.autoImport !== false ? (await nitro.unimport.generateTypeDeclarations({
103
+ exportHelper: false,
104
+ resolvePath: (i) => {
105
+ const from = i.typeFrom || i.from;
106
+ return resolvedImportPathMap.get(from) ?? from;
286
107
  }
108
+ })).trim() : ""
109
+ ];
110
+ }
111
+ const generateRoutes = () => [
112
+ "// Generated by nitro",
113
+ 'import type { Serialize, Simplify } from "nitro/types";',
114
+ 'declare module "nitro/types" {',
115
+ " type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T",
116
+ " interface InternalApi {",
117
+ ...Object.entries(types.routes).map(
118
+ ([path, methods]) => [
119
+ ` '${path}': {`,
120
+ ...Object.entries(methods).map(
121
+ ([method, types2]) => ` '${method}': ${types2.join(" | ")}`
122
+ ),
123
+ " }"
124
+ ].join("\n")
125
+ ),
126
+ " }",
127
+ "}",
128
+ // Makes this a module for augmentation purposes
129
+ "export {}"
130
+ ];
131
+ const config = [
132
+ "// Generated by nitro",
133
+ /* ts */
134
+ `declare module "nitro/types" {`,
135
+ nitro.options.typescript.generateRuntimeConfigTypes ? generateTypes(
136
+ await resolveSchema(
137
+ Object.fromEntries(
138
+ Object.entries(nitro.options.runtimeConfig).filter(
139
+ ([key]) => !["app", "nitro"].includes(key)
140
+ )
141
+ )
142
+ ),
143
+ {
144
+ interfaceName: "NitroRuntimeConfig",
145
+ addExport: false,
146
+ addDefaults: false,
147
+ allowExtraKeys: false,
148
+ indentation: 2
287
149
  }
288
- });
289
- Object.defineProperty(_route, "data", {
290
- get: () => {
291
- return dataBuff ? dataBuff.buffer : void 0;
292
- },
293
- set(value) {
294
- if (dataBuff) {
295
- dataBuff = Buffer.from(value);
150
+ ) : "",
151
+ `}`,
152
+ // Makes this a module for augmentation purposes
153
+ "export {}"
154
+ ];
155
+ const declarations = [
156
+ // local nitropack augmentations
157
+ '/// <reference path="./nitro-routes.d.ts" />',
158
+ '/// <reference path="./nitro-config.d.ts" />',
159
+ // global server auto-imports
160
+ '/// <reference path="./nitro-imports.d.ts" />'
161
+ ];
162
+ const buildFiles = [];
163
+ buildFiles.push({
164
+ path: join(typesDir, "nitro-routes.d.ts"),
165
+ contents: () => generateRoutes().join("\n")
166
+ });
167
+ buildFiles.push({
168
+ path: join(typesDir, "nitro-config.d.ts"),
169
+ contents: config.join("\n")
170
+ });
171
+ buildFiles.push({
172
+ path: join(typesDir, "nitro-imports.d.ts"),
173
+ contents: [...autoImportedTypes, autoImportExports || "export {}"].join(
174
+ "\n"
175
+ )
176
+ });
177
+ buildFiles.push({
178
+ path: join(typesDir, "nitro.d.ts"),
179
+ contents: declarations.join("\n")
180
+ });
181
+ if (nitro.options.typescript.generateTsConfig) {
182
+ const tsConfigPath = resolve(
183
+ nitro.options.buildDir,
184
+ nitro.options.typescript.tsconfigPath
185
+ );
186
+ const tsconfigDir = dirname(tsConfigPath);
187
+ const tsConfig = defu(nitro.options.typescript.tsConfig, {
188
+ compilerOptions: {
189
+ /* Base options: */
190
+ esModuleInterop: true,
191
+ allowSyntheticDefaultImports: true,
192
+ skipLibCheck: true,
193
+ target: "ESNext",
194
+ allowJs: true,
195
+ resolveJsonModule: true,
196
+ moduleDetection: "force",
197
+ isolatedModules: true,
198
+ verbatimModuleSyntax: true,
199
+ allowImportingTsExtensions: true,
200
+ /* Strictness */
201
+ strict: nitro.options.typescript.strict,
202
+ noUncheckedIndexedAccess: true,
203
+ noImplicitOverride: true,
204
+ forceConsistentCasingInFileNames: true,
205
+ /* If NOT transpiling with TypeScript: */
206
+ module: "Preserve",
207
+ jsx: "preserve",
208
+ jsxFactory: "h",
209
+ jsxFragmentFactory: "Fragment",
210
+ paths: {
211
+ "#imports": [
212
+ relativeWithDot(tsconfigDir, join(typesDir, "nitro-imports"))
213
+ ],
214
+ ...nitro.options.typescript.internalPaths ? {
215
+ "nitro/runtime": [
216
+ relativeWithDot(tsconfigDir, join(runtimeDir, "index"))
217
+ ],
218
+ "#internal/nitro": [
219
+ relativeWithDot(tsconfigDir, join(runtimeDir, "index"))
220
+ ],
221
+ "nitro/runtime/*": [
222
+ relativeWithDot(tsconfigDir, join(runtimeDir, "*"))
223
+ ],
224
+ "#internal/nitro/*": [
225
+ relativeWithDot(tsconfigDir, join(runtimeDir, "*"))
226
+ ]
227
+ } : {}
296
228
  }
297
- }
229
+ },
230
+ include: [
231
+ relativeWithDot(tsconfigDir, join(typesDir, "nitro.d.ts")).replace(
232
+ /^(?=[^.])/,
233
+ "./"
234
+ ),
235
+ join(relativeWithDot(tsconfigDir, nitro.options.rootDir), "**/*"),
236
+ ...nitro.options.srcDir === nitro.options.rootDir ? [] : [join(relativeWithDot(tsconfigDir, nitro.options.srcDir), "**/*")]
237
+ ]
298
238
  });
299
- const redirectCodes = [301, 302, 303, 304, 307, 308];
300
- if (![200, ...redirectCodes].includes(res.status)) {
301
- _route.error = new Error(`[${res.status}] ${res.statusText}`);
302
- _route.error.status = res.status;
303
- _route.error.statusText = res.statusText;
304
- }
305
- _route.generateTimeMS = Date.now() - start;
306
- const contentType = res.headers.get("content-type") || "";
307
- const isImplicitHTML = !route.endsWith(".html") && contentType.includes("html") && !JsonSigRx.test(dataBuff.subarray(0, 32).toString("utf8"));
308
- const routeWithIndex = route.endsWith("/") ? route + "index" : route;
309
- const htmlPath = route.endsWith("/") || nitro.options.prerender.autoSubfolderIndex ? joinURL(route, "index.html") : route + ".html";
310
- _route.fileName = withoutBase(
311
- isImplicitHTML ? htmlPath : routeWithIndex,
312
- nitro.options.baseURL
313
- );
314
- const inferredContentType = mime.getType(_route.fileName) || "text/plain";
315
- _route.contentType = contentType || inferredContentType;
316
- await nitro.hooks.callHook("prerender:generate", _route, nitro);
317
- if (_route.contentType !== inferredContentType) {
318
- nitro._prerenderMeta[_route.fileName] ||= {};
319
- nitro._prerenderMeta[_route.fileName].contentType = _route.contentType;
320
- }
321
- if (_route.error) {
322
- failedRoutes.add(_route);
323
- }
324
- if (_route.skip || _route.error) {
325
- await nitro.hooks.callHook("prerender:route", _route);
326
- nitro.logger.log(formatPrerenderRoute(_route));
327
- dataBuff = void 0;
328
- return _route;
329
- }
330
- if (canWriteToDisk(_route)) {
331
- const filePath = join(nitro.options.output.publicDir, _route.fileName);
332
- await writeFile(filePath, dataBuff);
333
- nitro._prerenderedRoutes.push(_route);
334
- } else {
335
- _route.skip = true;
336
- }
337
- if (!_route.error && (isImplicitHTML || route.endsWith(".html"))) {
338
- const extractedLinks = await extractLinks(
339
- dataBuff.toString("utf8"),
340
- route,
341
- res,
342
- nitro.options.prerender.crawlLinks
239
+ for (const alias in tsConfig.compilerOptions.paths) {
240
+ const paths = await Promise.all(
241
+ tsConfig.compilerOptions.paths[alias].map(async (path) => {
242
+ if (!isAbsolute(path)) {
243
+ return path;
244
+ }
245
+ const stats = await promises.stat(path).catch(
246
+ () => null
247
+ /* file does not exist */
248
+ );
249
+ return relativeWithDot(
250
+ tsconfigDir,
251
+ stats?.isFile() ? path.replace(/(?<=\w)\.\w+$/g, "") : path
252
+ );
253
+ })
343
254
  );
344
- for (const _link of extractedLinks) {
345
- if (canPrerender(_link)) {
346
- routes.add(_link);
347
- }
348
- }
255
+ tsConfig.compilerOptions.paths[alias] = [...new Set(paths)];
349
256
  }
350
- await nitro.hooks.callHook("prerender:route", _route);
351
- nitro.logger.log(formatPrerenderRoute(_route));
352
- dataBuff = void 0;
353
- return _route;
354
- };
355
- nitro.logger.info(
356
- nitro.options.prerender.crawlLinks ? `Prerendering ${routes.size} initial routes with crawler` : `Prerendering ${routes.size} routes`
357
- );
358
- await runParallel(routes, generateRoute, {
359
- concurrency: nitro.options.prerender.concurrency,
360
- interval: nitro.options.prerender.interval
361
- });
362
- await closePrerenderer();
363
- await nitro.hooks.callHook("prerender:done", {
364
- prerenderedRoutes: nitro._prerenderedRoutes,
365
- failedRoutes: [...failedRoutes]
366
- });
367
- if (nitro.options.prerender.failOnError && failedRoutes.size > 0) {
368
- nitro.logger.log("\nErrors prerendering:");
369
- for (const route of failedRoutes) {
370
- const parents = linkParents.get(route.route);
371
- parents?.size ? `
372
- ${[...parents.values()].map((link) => colors.gray(` \u2502 \u2514\u2500\u2500 Linked from ${link}`)).join("\n")}` : "";
373
- nitro.logger.log(formatPrerenderRoute(route));
257
+ tsConfig.include = [
258
+ ...new Set(
259
+ tsConfig.include.map(
260
+ (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
261
+ )
262
+ )
263
+ ];
264
+ if (tsConfig.exclude) {
265
+ tsConfig.exclude = [
266
+ ...new Set(
267
+ tsConfig.exclude.map(
268
+ (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
269
+ )
270
+ )
271
+ ];
374
272
  }
375
- nitro.logger.log("");
376
- throw new Error("Exiting due to prerender errors.");
377
- }
378
- const prerenderTimeInMs = Date.now() - prerenderStartTime;
379
- nitro.logger.info(
380
- `Prerendered ${nitro._prerenderedRoutes.length} routes in ${prerenderTimeInMs / 1e3} seconds`
381
- );
382
- if (nitro.options.compressPublicAssets) {
383
- await compressPublicAssets(nitro);
384
- }
385
- }
386
-
387
- const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]);
388
- const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias");
389
- function normalizeAliases(_aliases) {
390
- if (_aliases[normalizedAliasSymbol]) {
391
- return _aliases;
273
+ types.tsConfig = tsConfig;
274
+ buildFiles.push({
275
+ path: tsConfigPath,
276
+ contents: () => JSON.stringify(tsConfig, null, 2)
277
+ });
392
278
  }
393
- const aliases = Object.fromEntries(
394
- Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b))
279
+ await nitro.hooks.callHook("types:extend", types);
280
+ await Promise.all(
281
+ buildFiles.map(async (file) => {
282
+ await writeFile(
283
+ resolve(nitro.options.buildDir, file.path),
284
+ typeof file.contents === "string" ? file.contents : file.contents()
285
+ );
286
+ })
395
287
  );
396
- for (const key in aliases) {
397
- for (const alias in aliases) {
398
- if (alias === key || key.startsWith(alias)) {
399
- continue;
400
- }
401
- if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) {
402
- aliases[key] = aliases[alias] + aliases[key].slice(alias.length);
403
- }
404
- }
405
- }
406
- Object.defineProperty(aliases, normalizedAliasSymbol, {
407
- value: true,
408
- enumerable: false
409
- });
410
- return aliases;
411
288
  }
412
- function resolveAlias(path, aliases) {
413
- const _path = normalizeWindowsPath(path);
414
- aliases = normalizeAliases(aliases);
415
- for (const [alias, to] of Object.entries(aliases)) {
416
- if (!_path.startsWith(alias)) {
417
- continue;
418
- }
419
- const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias;
420
- if (hasTrailingSlash(_path[_alias.length])) {
421
- return join(to, _path.slice(alias.length));
422
- }
423
- }
424
- return _path;
425
- }
426
- function _compareAliases(a, b) {
427
- return b.split("/").length - a.split("/").length;
428
- }
429
- function hasTrailingSlash(path = "/") {
430
- const lastChar = path[path.length - 1];
431
- return lastChar === "/" || lastChar === "\\";
289
+ const RELATIVE_RE = /^\.{1,2}\//;
290
+ function relativeWithDot(from, to) {
291
+ const rel = relative(from, to);
292
+ return RELATIVE_RE.test(rel) ? rel : "./" + rel;
432
293
  }
433
294
 
434
- function getType(val) {
435
- const type = typeof val;
436
- if (type === "undefined" || val === null) {
437
- return void 0;
438
- }
439
- if (Array.isArray(val)) {
440
- return "array";
441
- }
442
- return type;
443
- }
444
- function isObject(val) {
445
- return val !== null && !Array.isArray(val) && typeof val === "object";
446
- }
447
- function nonEmpty(arr) {
448
- return arr.filter(Boolean);
449
- }
450
- function unique(arr) {
451
- return [...new Set(arr)];
452
- }
453
- function joinPath(a, b = "", sep = ".") {
454
- return a ? a + sep + b : b;
455
- }
456
- function setValue(obj, path, val) {
457
- const keys = path.split(".");
458
- const _key = keys.pop();
459
- for (const key of keys) {
460
- if (!obj || typeof obj !== "object") {
461
- return;
462
- }
463
- if (!(key in obj)) {
464
- obj[key] = {};
465
- }
466
- obj = obj[key];
467
- }
468
- if (_key) {
469
- if (!obj || typeof obj !== "object") {
470
- return;
471
- }
472
- obj[_key] = val;
473
- }
474
- }
475
- function getValue(obj, path) {
476
- for (const key of path.split(".")) {
477
- if (!obj || typeof obj !== "object" || !(key in obj)) {
295
+ async function runParallel(inputs, cb, opts) {
296
+ const tasks = /* @__PURE__ */ new Set();
297
+ function queueNext() {
298
+ const route = inputs.values().next().value;
299
+ if (!route) {
478
300
  return;
479
301
  }
480
- obj = obj[key];
302
+ inputs.delete(route);
303
+ const task = (opts.interval ? new Promise((resolve) => setTimeout(resolve, opts.interval)) : Promise.resolve()).then(() => cb(route)).catch((error) => {
304
+ console.error(error);
305
+ });
306
+ tasks.add(task);
307
+ return task.then(() => {
308
+ tasks.delete(task);
309
+ if (inputs.size > 0) {
310
+ return refillQueue();
311
+ }
312
+ });
481
313
  }
482
- return obj;
483
- }
484
- function normalizeTypes(val) {
485
- const arr = unique(val.filter(Boolean));
486
- if (arr.length === 0 || arr.includes("any")) {
487
- return;
314
+ function refillQueue() {
315
+ const workers = Math.min(opts.concurrency - tasks.size, inputs.size);
316
+ return Promise.all(Array.from({ length: workers }, () => queueNext()));
488
317
  }
489
- return arr.length > 1 ? arr : arr[0];
318
+ await refillQueue();
490
319
  }
491
320
 
492
- async function resolveSchema(obj, defaults, options = {}) {
493
- const schema = await _resolveSchema(obj, "", {
494
- root: obj,
495
- defaults,
496
- resolveCache: {},
497
- ignoreDefaults: !!options.ignoreDefaults
498
- });
499
- return schema;
321
+ const allowedExtensions = /* @__PURE__ */ new Set(["", ".json"]);
322
+ const linkParents$1 = /* @__PURE__ */ new Map();
323
+ const HTML_ENTITIES = {
324
+ "&lt;": "<",
325
+ "&gt;": ">",
326
+ "&amp;": "&",
327
+ "&apos;": "'",
328
+ "&quot;": '"'
329
+ };
330
+ function escapeHtml(text) {
331
+ return text.replace(
332
+ /&(lt|gt|amp|apos|quot);/g,
333
+ (ch) => HTML_ENTITIES[ch] || ch
334
+ );
500
335
  }
501
- async function _resolveSchema(input, id, ctx) {
502
- if (id in ctx.resolveCache) {
503
- return ctx.resolveCache[id];
504
- }
505
- const schemaId = "#" + id.replace(/\./g, "/");
506
- if (!isObject(input)) {
507
- const safeInput = Array.isArray(input) ? [...input] : input;
508
- const schema2 = {
509
- type: getType(input),
510
- id: schemaId,
511
- default: ctx.ignoreDefaults ? void 0 : safeInput
512
- };
513
- normalizeSchema(schema2, { ignoreDefaults: ctx.ignoreDefaults });
514
- ctx.resolveCache[id] = schema2;
515
- if (ctx.defaults && getValue(ctx.defaults, id) === void 0) {
516
- setValue(ctx.defaults, id, schema2.default);
517
- }
518
- return schema2;
519
- }
520
- const node = { ...input };
521
- const schema = ctx.resolveCache[id] = {
522
- ...node.$schema,
523
- id: schemaId
524
- };
525
- for (const key in node) {
526
- if (key === "$resolve" || key === "$schema" || key === "$default") {
527
- continue;
528
- }
529
- schema.properties = schema.properties || {};
530
- if (!schema.properties[key]) {
531
- const child = schema.properties[key] = await _resolveSchema(
532
- node[key],
533
- joinPath(id, key),
534
- ctx
535
- );
536
- if (Array.isArray(child.tags) && child.tags.includes("@required")) {
537
- schema.required = schema.required || [];
538
- if (!schema.required.includes(key)) {
539
- schema.required.push(key);
540
- }
336
+ async function extractLinks(html, from, res, crawlLinks) {
337
+ const links = [];
338
+ const _links = [];
339
+ if (crawlLinks) {
340
+ await z(P(html), (node) => {
341
+ if (!node.attributes?.href) {
342
+ return;
541
343
  }
542
- }
344
+ const link = escapeHtml(node.attributes.href);
345
+ if (!decodeURIComponent(link).startsWith("#") && allowedExtensions.has(getExtension(link))) {
346
+ _links.push(link);
347
+ }
348
+ });
543
349
  }
544
- if (!ctx.ignoreDefaults) {
545
- if (ctx.defaults) {
546
- schema.default = getValue(ctx.defaults, id);
547
- }
548
- if (schema.default === void 0 && "$default" in node) {
549
- schema.default = node.$default;
550
- }
551
- if (typeof node.$resolve === "function") {
552
- schema.default = await node.$resolve(schema.default, async (key) => {
553
- return (await _resolveSchema(getValue(ctx.root, key), key, ctx)).default;
554
- });
350
+ const header = res.headers.get("x-nitro-prerender") || "";
351
+ _links.push(...header.split(",").map((i) => decodeURIComponent(i.trim())));
352
+ for (const link of _links.filter(Boolean)) {
353
+ const _link = parseURL(link);
354
+ if (_link.protocol || _link.host) {
355
+ continue;
555
356
  }
556
- }
557
- if (ctx.defaults) {
558
- setValue(ctx.defaults, id, schema.default);
559
- }
560
- if (!schema.type) {
561
- schema.type = getType(schema.default) || (schema.properties ? "object" : "any");
562
- }
563
- normalizeSchema(schema, { ignoreDefaults: ctx.ignoreDefaults });
564
- if (ctx.defaults && getValue(ctx.defaults, id) === void 0) {
565
- setValue(ctx.defaults, id, schema.default);
566
- }
567
- return schema;
568
- }
569
- function normalizeSchema(schema, options) {
570
- if (schema.type === "array" && !("items" in schema)) {
571
- schema.items = {
572
- type: nonEmpty(unique(schema.default.map((i) => getType(i))))
573
- };
574
- if (schema.items.type) {
575
- if (schema.items.type.length === 0) {
576
- schema.items.type = "any";
577
- } else if (schema.items.type.length === 1) {
578
- schema.items.type = schema.items.type[0];
579
- }
357
+ if (!_link.pathname.startsWith("/")) {
358
+ const fromURL = new URL(from, "http://localhost");
359
+ _link.pathname = new URL(_link.pathname, fromURL).pathname;
580
360
  }
361
+ links.push(_link.pathname + _link.search);
581
362
  }
582
- if (!options.ignoreDefaults && schema.default === void 0 && ("properties" in schema || schema.type === "object" || schema.type === "any")) {
583
- const propsWithDefaults = Object.entries(schema.properties || {}).filter(([, prop]) => "default" in prop).map(([key, value]) => [key, value.default]);
584
- schema.default = Object.fromEntries(propsWithDefaults);
585
- }
586
- }
587
-
588
- const GenerateTypesDefaults = {
589
- interfaceName: "Untyped",
590
- addExport: true,
591
- addDefaults: true,
592
- allowExtraKeys: void 0,
593
- partial: false,
594
- indentation: 0
595
- };
596
- const TYPE_MAP = {
597
- array: "any[]",
598
- bigint: "bigint",
599
- boolean: "boolean",
600
- number: "number",
601
- object: "",
602
- // Will be precisely defined
603
- any: "any",
604
- string: "string",
605
- symbol: "Symbol",
606
- function: "Function"
607
- };
608
- const SCHEMA_KEYS = /* @__PURE__ */ new Set([
609
- "items",
610
- "default",
611
- "resolve",
612
- "properties",
613
- "title",
614
- "description",
615
- "$schema",
616
- "type",
617
- "tsType",
618
- "markdownType",
619
- "tags",
620
- "args",
621
- "id",
622
- "returns"
623
- ]);
624
- const DECLARATION_RE = /typeof import\(["'](?<source>[^)]+)["']\)(\.(?<type>\w+)|\[["'](?<type1>\w+)["']])/g;
625
- function extractTypeImports(declarations) {
626
- const typeImports = {};
627
- const aliases = /* @__PURE__ */ new Set();
628
- const imports = [];
629
- for (const match of declarations.matchAll(DECLARATION_RE)) {
630
- const { source, type1, type = type1 } = match.groups || {};
631
- typeImports[source] = typeImports[source] || /* @__PURE__ */ new Set();
632
- typeImports[source].add(type);
633
- }
634
- for (const source in typeImports) {
635
- const sourceImports = [];
636
- for (const type of typeImports[source]) {
637
- let count = 0;
638
- let alias = type;
639
- while (aliases.has(alias)) {
640
- alias = `${type}${count++}`;
641
- }
642
- aliases.add(alias);
643
- sourceImports.push(alias === type ? type : `${type} as ${alias}`);
644
- declarations = declarations.replace(
645
- new RegExp(
646
- `typeof import\\(['"]${source}['"]\\)(\\.${type}|\\[['"]${type}['"]\\])`,
647
- "g"
648
- ),
649
- alias
650
- );
363
+ for (const link of links) {
364
+ const _parents = linkParents$1.get(link);
365
+ if (_parents) {
366
+ _parents.add(from);
367
+ } else {
368
+ linkParents$1.set(link, /* @__PURE__ */ new Set([from]));
651
369
  }
652
- imports.push(
653
- `import type { ${sourceImports.join(", ")} } from '${source}'`
654
- );
655
370
  }
656
- return [...imports, declarations].join("\n");
371
+ return links;
657
372
  }
658
- function generateTypes(schema, opts = {}) {
659
- opts = { ...GenerateTypesDefaults, ...opts };
660
- const baseIden = " ".repeat(opts.indentation || 0);
661
- const interfaceCode = `interface ${opts.interfaceName} {
662
- ` + _genTypes(schema, baseIden + " ", opts).map((l) => l.trim().length > 0 ? l : "").join("\n") + `
663
- ${baseIden}}`;
664
- if (!opts.addExport) {
665
- return baseIden + interfaceCode;
666
- }
667
- return extractTypeImports(baseIden + `export ${interfaceCode}`);
373
+ const EXT_REGEX = /\.[\da-z]+$/;
374
+ function getExtension(link) {
375
+ const pathname = parseURL(link).pathname;
376
+ return (pathname.match(EXT_REGEX) || [])[0] || "";
668
377
  }
669
- function _genTypes(schema, spaces, opts) {
670
- const buff = [];
671
- if (!schema) {
672
- return buff;
673
- }
674
- for (const key in schema.properties) {
675
- const val = schema.properties[key];
676
- buff.push(...generateJSDoc(val, opts));
677
- if (val.tsType) {
678
- buff.push(
679
- `${genObjectKey(key)}${isRequired(schema, key, opts) ? "" : "?"}: ${val.tsType},
680
- `
681
- );
682
- } else if (val.type === "object") {
683
- buff.push(
684
- `${genObjectKey(key)}${isRequired(schema, key, opts) ? "" : "?"}: {`,
685
- ..._genTypes(val, spaces, opts),
686
- "},\n"
687
- );
688
- } else {
689
- let type;
690
- if (val.type === "array") {
691
- type = `Array<${getTsType(val.items || [], opts)}>`;
692
- } else if (val.type === "function") {
693
- type = genFunctionType(val, opts);
694
- } else {
695
- type = getTsType(val, opts);
696
- }
697
- buff.push(
698
- `${genObjectKey(key)}${isRequired(schema, key, opts) ? "" : "?"}: ${type},
699
- `
700
- );
378
+ function formatPrerenderRoute(route) {
379
+ let str = ` \u251C\u2500 ${route.route} (${route.generateTimeMS}ms)`;
380
+ if (route.error) {
381
+ const parents = linkParents$1.get(route.route);
382
+ const errorColor = colors[route.error.status === 404 ? "yellow" : "red"];
383
+ const errorLead = parents?.size ? "\u251C\u2500\u2500" : "\u2514\u2500\u2500";
384
+ str += `
385
+ \u2502 ${errorLead} ${errorColor(route.error.message)}`;
386
+ if (parents?.size) {
387
+ str += `
388
+ ${[...parents.values()].map((link) => ` \u2502 \u2514\u2500\u2500 Linked from ${link}`).join("\n")}`;
701
389
  }
702
390
  }
703
- if (buff.length > 0) {
704
- const last = buff.pop() || "";
705
- buff.push(last.slice(0, Math.max(0, last.length - 1)));
706
- }
707
- if (opts.allowExtraKeys === true || buff.length === 0 && opts.allowExtraKeys !== false) {
708
- buff.push("[key: string]: any");
391
+ if (route.skip) {
392
+ str += colors.gray(" (skipped)");
709
393
  }
710
- return buff.flatMap((l) => l.split("\n")).map((l) => spaces + l);
394
+ return colors.gray(str);
711
395
  }
712
- function getTsType(type, opts) {
713
- if (Array.isArray(type)) {
714
- return [normalizeTypes(type.map((t) => getTsType(t, opts)))].flat().join("|") || "any";
715
- }
716
- if (!type) {
717
- return "any";
396
+ function matchesIgnorePattern(path, pattern) {
397
+ if (typeof pattern === "string") {
398
+ return path.startsWith(pattern);
718
399
  }
719
- if (type.tsType) {
720
- return type.tsType;
400
+ if (typeof pattern === "function") {
401
+ return pattern(path) === true;
721
402
  }
722
- if (!type.type) {
723
- return "any";
403
+ if (pattern instanceof RegExp) {
404
+ return pattern.test(path);
724
405
  }
725
- if (Array.isArray(type.type)) {
726
- return type.type.map((t) => {
727
- if (t === "object" && type.type.length > 1) {
728
- return `{
729
- ` + _genTypes(type, " ", opts).join("\n") + `
730
- }`;
731
- }
732
- return TYPE_MAP[t];
733
- }).join("|");
406
+ return false;
407
+ }
408
+
409
+ const JsonSigRx = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
410
+ const linkParents = /* @__PURE__ */ new Map();
411
+ async function prerender(nitro) {
412
+ if (nitro.options.noPublicDir) {
413
+ nitro.logger.warn(
414
+ "Skipping prerender since `noPublicDir` option is enabled."
415
+ );
416
+ return;
734
417
  }
735
- if (type.type === "array") {
736
- return `Array<${getTsType(type.items || [], opts)}>`;
418
+ if (nitro.options.builder === "vite") {
419
+ nitro.logger.warn(
420
+ "Skipping prerender since not supported with vite builder yet..."
421
+ );
422
+ return;
737
423
  }
738
- if (type.type === "object") {
739
- return `{
740
- ` + _genTypes(type, " ", opts).join("\n") + `
741
- }`;
424
+ const routes = new Set(nitro.options.prerender.routes);
425
+ const prerenderRulePaths = Object.entries(nitro.options.routeRules).filter(([path2, options]) => options.prerender && !path2.includes("*")).map((e) => e[0]);
426
+ for (const route of prerenderRulePaths) {
427
+ routes.add(route);
742
428
  }
743
- return TYPE_MAP[type.type] || type.type;
744
- }
745
- function genFunctionType(schema, opts) {
746
- return `(${genFunctionArgs(schema.args, opts)}) => ${getTsType(
747
- schema.returns || [],
748
- opts
749
- )}`;
750
- }
751
- function genFunctionArgs(args, opts) {
752
- return args?.map((arg) => {
753
- let argStr = arg.name;
754
- if (arg.optional || arg.default) {
755
- argStr += "?";
756
- }
757
- if (arg.type || arg.tsType) {
758
- argStr += `: ${getTsType(arg, opts)}`;
429
+ await nitro.hooks.callHook("prerender:routes", routes);
430
+ if (routes.size === 0) {
431
+ if (nitro.options.prerender.crawlLinks) {
432
+ routes.add("/");
433
+ } else {
434
+ return;
759
435
  }
760
- return argStr;
761
- }).join(", ") || "";
762
- }
763
- function generateJSDoc(schema, opts) {
764
- opts.defaultDescription = opts.defaultDescription || opts.defaultDescrption;
765
- let buff = [];
766
- if (schema.title) {
767
- buff.push(schema.title, "");
768
436
  }
769
- if (schema.description) {
770
- buff.push(schema.description, "");
771
- } else if (opts.defaultDescription && schema.type !== "object") {
772
- buff.push(opts.defaultDescription, "");
437
+ nitro.logger.info("Initializing prerenderer");
438
+ nitro._prerenderedRoutes = [];
439
+ nitro._prerenderMeta = nitro._prerenderMeta || {};
440
+ const prerendererConfig = {
441
+ ...nitro.options._config,
442
+ static: false,
443
+ rootDir: nitro.options.rootDir,
444
+ logLevel: 0,
445
+ preset: "nitro-prerender"
446
+ };
447
+ await nitro.hooks.callHook("prerender:config", prerendererConfig);
448
+ const nitroRenderer = await createNitro(prerendererConfig);
449
+ const prerenderStartTime = Date.now();
450
+ await nitro.hooks.callHook("prerender:init", nitroRenderer);
451
+ let path = relative(nitro.options.output.dir, nitro.options.output.publicDir);
452
+ if (!path.startsWith(".")) {
453
+ path = `./${path}`;
773
454
  }
774
- if (opts.addDefaults && schema.type !== "object" && schema.type !== "any" && !(Array.isArray(schema.default) && schema.default.length === 0)) {
775
- const stringified = JSON.stringify(schema.default);
776
- if (stringified) {
777
- buff.push(`@default ${stringified.replace(/\*\//g, String.raw`*\/`)}`);
778
- }
455
+ nitroRenderer.options.commands.preview = `npx serve ${path}`;
456
+ nitroRenderer.options.output.dir = nitro.options.output.dir;
457
+ await build(nitroRenderer);
458
+ const serverFilename = typeof nitroRenderer.options.rollupConfig?.output?.entryFileNames === "string" ? nitroRenderer.options.rollupConfig.output.entryFileNames : "index.mjs";
459
+ const serverEntrypoint = resolve(
460
+ nitroRenderer.options.output.serverDir,
461
+ serverFilename
462
+ );
463
+ const { closePrerenderer, appFetch } = await import(pathToFileURL(serverEntrypoint).href);
464
+ const routeRules = createRouter();
465
+ for (const [route, rules] of Object.entries(nitro.options.routeRules)) {
466
+ addRoute(routeRules, void 0, route, rules);
779
467
  }
780
- for (const key in schema) {
781
- if (!SCHEMA_KEYS.has(key)) {
782
- buff.push("", `@${key} ${schema[key]}`);
468
+ const _getRouteRules = (path2) => defu(
469
+ {},
470
+ ...findAllRoutes(routeRules, void 0, path2).map((r) => r.data).reverse()
471
+ );
472
+ const generatedRoutes = /* @__PURE__ */ new Set();
473
+ const failedRoutes = /* @__PURE__ */ new Set();
474
+ const skippedRoutes = /* @__PURE__ */ new Set();
475
+ const displayedLengthWarns = /* @__PURE__ */ new Set();
476
+ const publicAssetBases = nitro.options.publicAssets.filter(
477
+ (a) => !!a.baseURL && a.baseURL !== "/" && !a.fallthrough
478
+ ).map((a) => withTrailingSlash(a.baseURL));
479
+ const scannedPublicAssets = nitro.options.prerender.ignoreUnprefixedPublicAssets ? new Set(await scanUnprefixedPublicAssets(nitro)) : /* @__PURE__ */ new Set();
480
+ const canPrerender = (route = "/") => {
481
+ if (generatedRoutes.has(route) || skippedRoutes.has(route)) {
482
+ return false;
783
483
  }
784
- }
785
- if (Array.isArray(schema.tags)) {
786
- for (const tag of schema.tags) {
787
- if (tag !== "@untyped") {
788
- buff.push("", tag);
484
+ for (const pattern of nitro.options.prerender.ignore) {
485
+ if (matchesIgnorePattern(route, pattern)) {
486
+ return false;
789
487
  }
790
488
  }
791
- }
792
- buff = buff.flatMap((i) => i.split("\n"));
793
- if (buff.length > 0) {
794
- return buff.length === 1 ? ["/** " + buff[0] + " */"] : ["/**", ...buff.map((i) => ` * ${i}`), "*/"];
795
- }
796
- return [];
797
- }
798
- function isRequired(schema, key, opts) {
799
- if (Array.isArray(schema.required) && schema.required.includes(key)) {
489
+ if (publicAssetBases.some((base) => route.startsWith(base))) {
490
+ return false;
491
+ }
492
+ if (scannedPublicAssets.has(route)) {
493
+ return false;
494
+ }
495
+ if (_getRouteRules(route).prerender === false) {
496
+ return false;
497
+ }
800
498
  return true;
801
- }
802
- return !opts.partial;
803
- }
804
-
805
- async function writeTypes(nitro) {
806
- const types = {
807
- routes: {}
808
499
  };
809
- const typesDir = resolve(nitro.options.buildDir, "types");
810
- const middleware = [...nitro.scannedHandlers, ...nitro.options.handlers];
811
- for (const mw of middleware) {
812
- if (typeof mw.handler !== "string" || !mw.route) {
813
- continue;
814
- }
815
- const relativePath = relative(
816
- typesDir,
817
- resolveNitroPath(mw.handler, nitro.options)
818
- ).replace(/\.(js|mjs|cjs|ts|mts|cts|tsx|jsx)$/, "");
819
- const method = mw.method || "default";
820
- types.routes[mw.route] ??= {};
821
- types.routes[mw.route][method] ??= [];
822
- types.routes[mw.route][method].push(
823
- `Simplify<Serialize<Awaited<ReturnType<typeof import('${relativePath}').default>>>>`
824
- );
825
- }
826
- let autoImportedTypes = [];
827
- let autoImportExports = "";
828
- if (nitro.unimport) {
829
- await nitro.unimport.init();
830
- const allImports = await nitro.unimport.getImports();
831
- autoImportExports = toExports(allImports).replace(
832
- /#internal\/nitro/g,
833
- relative(typesDir, runtimeDir)
834
- );
835
- const resolvedImportPathMap = /* @__PURE__ */ new Map();
836
- for (const i of allImports) {
837
- if (resolvedImportPathMap.has(i.from)) {
838
- continue;
839
- }
840
- let path = resolveAlias(i.from, nitro.options.alias);
841
- if (!isAbsolute(path)) {
842
- const resolvedPath = resolveModulePath(i.from, {
843
- try: true,
844
- from: nitro.options.nodeModulesDirs,
845
- conditions: ["type", "node", "import"],
846
- suffixes: ["", "/index"],
847
- extensions: [".mjs", ".cjs", ".js", ".mts", ".cts", ".ts"]
848
- });
849
- if (resolvedPath) {
850
- const { dir, name } = parseNodeModulePath(resolvedPath);
851
- if (!dir || !name) {
852
- path = resolvedPath;
853
- } else {
854
- const subpath = await lookupNodeModuleSubpath(resolvedPath);
855
- path = join(dir, name, subpath || "");
856
- }
857
- }
858
- }
859
- if (existsSync(path) && !await isDirectory(path)) {
860
- path = path.replace(/\.[a-z]+$/, "");
861
- }
862
- if (isAbsolute(path)) {
863
- path = relative(typesDir, path);
864
- }
865
- resolvedImportPathMap.set(i.from, path);
500
+ const canWriteToDisk = (route) => {
501
+ if (route.route.includes("?")) {
502
+ return false;
866
503
  }
867
- autoImportedTypes = [
868
- nitro.options.imports && nitro.options.imports.autoImport !== false ? (await nitro.unimport.generateTypeDeclarations({
869
- exportHelper: false,
870
- resolvePath: (i) => resolvedImportPathMap.get(i.from) ?? i.from
871
- })).trim() : ""
872
- ];
873
- }
874
- const generateRoutes = () => [
875
- "// Generated by nitro",
876
- 'import type { Serialize, Simplify } from "nitro/types";',
877
- 'declare module "nitro/types" {',
878
- " type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T",
879
- " interface InternalApi {",
880
- ...Object.entries(types.routes).map(
881
- ([path, methods]) => [
882
- ` '${path}': {`,
883
- ...Object.entries(methods).map(
884
- ([method, types2]) => ` '${method}': ${types2.join(" | ")}`
885
- ),
886
- " }"
887
- ].join("\n")
888
- ),
889
- " }",
890
- "}",
891
- // Makes this a module for augmentation purposes
892
- "export {}"
893
- ];
894
- const config = [
895
- "// Generated by nitro",
896
- /* ts */
897
- `declare module "nitro/types" {`,
898
- nitro.options.typescript.generateRuntimeConfigTypes ? generateTypes(
899
- await resolveSchema(
900
- Object.fromEntries(
901
- Object.entries(nitro.options.runtimeConfig).filter(
902
- ([key]) => !["app", "nitro"].includes(key)
903
- )
904
- )
905
- ),
906
- {
907
- interfaceName: "NitroRuntimeConfig",
908
- addExport: false,
909
- addDefaults: false,
910
- allowExtraKeys: false,
911
- indentation: 2
504
+ const FS_MAX_SEGMENT = 255;
505
+ const FS_MAX_PATH = 1024;
506
+ const FS_MAX_PATH_PUBLIC_HTML = FS_MAX_PATH - (nitro.options.output.publicDir.length + 10);
507
+ if ((route.route.length >= FS_MAX_PATH_PUBLIC_HTML || route.route.split("/").some((s) => s.length > FS_MAX_SEGMENT)) && !displayedLengthWarns.has(route)) {
508
+ displayedLengthWarns.add(route);
509
+ const _route = route.route.slice(0, 60) + "...";
510
+ if (route.route.length >= FS_MAX_PATH_PUBLIC_HTML) {
511
+ nitro.logger.warn(
512
+ `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}\`.`
513
+ );
514
+ } else {
515
+ nitro.logger.warn(
516
+ `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.`
517
+ );
518
+ return false;
912
519
  }
913
- ) : "",
914
- `}`,
915
- // Makes this a module for augmentation purposes
916
- "export {}"
917
- ];
918
- const declarations = [
919
- // local nitropack augmentations
920
- '/// <reference path="./nitro-routes.d.ts" />',
921
- '/// <reference path="./nitro-config.d.ts" />',
922
- // global server auto-imports
923
- '/// <reference path="./nitro-imports.d.ts" />'
924
- ];
925
- const buildFiles = [];
926
- buildFiles.push({
927
- path: join(typesDir, "nitro-routes.d.ts"),
928
- contents: () => generateRoutes().join("\n")
929
- });
930
- buildFiles.push({
931
- path: join(typesDir, "nitro-config.d.ts"),
932
- contents: config.join("\n")
933
- });
934
- buildFiles.push({
935
- path: join(typesDir, "nitro-imports.d.ts"),
936
- contents: [...autoImportedTypes, autoImportExports || "export {}"].join(
937
- "\n"
938
- )
939
- });
940
- buildFiles.push({
941
- path: join(typesDir, "nitro.d.ts"),
942
- contents: declarations.join("\n")
943
- });
944
- if (nitro.options.typescript.generateTsConfig) {
945
- const tsConfigPath = resolve(
946
- nitro.options.buildDir,
947
- nitro.options.typescript.tsconfigPath
948
- );
949
- const tsconfigDir = dirname(tsConfigPath);
950
- const tsConfig = defu(nitro.options.typescript.tsConfig, {
951
- compilerOptions: {
952
- /* Base options: */
953
- esModuleInterop: true,
954
- allowSyntheticDefaultImports: true,
955
- skipLibCheck: true,
956
- target: "ESNext",
957
- allowJs: true,
958
- resolveJsonModule: true,
959
- moduleDetection: "force",
960
- isolatedModules: true,
961
- verbatimModuleSyntax: true,
962
- allowImportingTsExtensions: true,
963
- /* Strictness */
964
- strict: nitro.options.typescript.strict,
965
- noUncheckedIndexedAccess: true,
966
- noImplicitOverride: true,
967
- forceConsistentCasingInFileNames: true,
968
- /* If NOT transpiling with TypeScript: */
969
- module: "Preserve",
970
- jsx: "preserve",
971
- jsxFactory: "h",
972
- jsxFragmentFactory: "Fragment",
973
- paths: {
974
- "#imports": [
975
- relativeWithDot(tsconfigDir, join(typesDir, "nitro-imports"))
976
- ],
977
- ...nitro.options.typescript.internalPaths ? {
978
- "nitro/runtime": [
979
- relativeWithDot(tsconfigDir, join(runtimeDir, "index"))
980
- ],
981
- "#internal/nitro": [
982
- relativeWithDot(tsconfigDir, join(runtimeDir, "index"))
983
- ],
984
- "nitro/runtime/*": [
985
- relativeWithDot(tsconfigDir, join(runtimeDir, "*"))
986
- ],
987
- "#internal/nitro/*": [
988
- relativeWithDot(tsconfigDir, join(runtimeDir, "*"))
989
- ]
990
- } : {}
520
+ }
521
+ return true;
522
+ };
523
+ const generateRoute = async (route) => {
524
+ const start = Date.now();
525
+ route = decodeURI(route);
526
+ if (!canPrerender(route)) {
527
+ skippedRoutes.add(route);
528
+ return;
529
+ }
530
+ generatedRoutes.add(route);
531
+ const _route = { route };
532
+ const encodedRoute = encodeURI(route);
533
+ const res = await appFetch(withBase(encodedRoute, nitro.options.baseURL), {
534
+ headers: [["x-nitro-prerender", encodedRoute]]
535
+ // TODO
536
+ // retry: nitro.options.prerender.retry,
537
+ // retryDelay: nitro.options.prerender.retryDelay,
538
+ });
539
+ let dataBuff = Buffer.from(await res.arrayBuffer());
540
+ Object.defineProperty(_route, "contents", {
541
+ get: () => {
542
+ return dataBuff ? dataBuff.toString("utf8") : void 0;
543
+ },
544
+ set(value) {
545
+ if (dataBuff) {
546
+ dataBuff = Buffer.from(value);
991
547
  }
548
+ }
549
+ });
550
+ Object.defineProperty(_route, "data", {
551
+ get: () => {
552
+ return dataBuff ? dataBuff.buffer : void 0;
992
553
  },
993
- include: [
994
- relativeWithDot(tsconfigDir, join(typesDir, "nitro.d.ts")).replace(
995
- /^(?=[^.])/,
996
- "./"
997
- ),
998
- join(relativeWithDot(tsconfigDir, nitro.options.rootDir), "**/*"),
999
- ...nitro.options.srcDir === nitro.options.rootDir ? [] : [join(relativeWithDot(tsconfigDir, nitro.options.srcDir), "**/*")]
1000
- ]
554
+ set(value) {
555
+ if (dataBuff) {
556
+ dataBuff = Buffer.from(value);
557
+ }
558
+ }
1001
559
  });
1002
- for (const alias in tsConfig.compilerOptions.paths) {
1003
- const paths = await Promise.all(
1004
- tsConfig.compilerOptions.paths[alias].map(async (path) => {
1005
- if (!isAbsolute(path)) {
1006
- return path;
1007
- }
1008
- const stats = await promises.stat(path).catch(
1009
- () => null
1010
- /* file does not exist */
1011
- );
1012
- return relativeWithDot(
1013
- tsconfigDir,
1014
- stats?.isFile() ? path.replace(/(?<=\w)\.\w+$/g, "") : path
1015
- );
1016
- })
560
+ const redirectCodes = [301, 302, 303, 304, 307, 308];
561
+ if (![200, ...redirectCodes].includes(res.status)) {
562
+ _route.error = new Error(`[${res.status}] ${res.statusText}`);
563
+ _route.error.status = res.status;
564
+ _route.error.statusText = res.statusText;
565
+ }
566
+ _route.generateTimeMS = Date.now() - start;
567
+ const contentType = res.headers.get("content-type") || "";
568
+ const isImplicitHTML = !route.endsWith(".html") && contentType.includes("html") && !JsonSigRx.test(dataBuff.subarray(0, 32).toString("utf8"));
569
+ const routeWithIndex = route.endsWith("/") ? route + "index" : route;
570
+ const htmlPath = route.endsWith("/") || nitro.options.prerender.autoSubfolderIndex ? joinURL(route, "index.html") : route + ".html";
571
+ _route.fileName = withoutBase(
572
+ isImplicitHTML ? htmlPath : routeWithIndex,
573
+ nitro.options.baseURL
574
+ );
575
+ const inferredContentType = mime.getType(_route.fileName) || "text/plain";
576
+ _route.contentType = contentType || inferredContentType;
577
+ await nitro.hooks.callHook("prerender:generate", _route, nitro);
578
+ if (_route.contentType !== inferredContentType) {
579
+ nitro._prerenderMeta[_route.fileName] ||= {};
580
+ nitro._prerenderMeta[_route.fileName].contentType = _route.contentType;
581
+ }
582
+ if (_route.error) {
583
+ failedRoutes.add(_route);
584
+ }
585
+ if (_route.skip || _route.error) {
586
+ await nitro.hooks.callHook("prerender:route", _route);
587
+ nitro.logger.log(formatPrerenderRoute(_route));
588
+ dataBuff = void 0;
589
+ return _route;
590
+ }
591
+ if (canWriteToDisk(_route)) {
592
+ const filePath = join(nitro.options.output.publicDir, _route.fileName);
593
+ await writeFile(filePath, dataBuff);
594
+ nitro._prerenderedRoutes.push(_route);
595
+ } else {
596
+ _route.skip = true;
597
+ }
598
+ if (!_route.error && (isImplicitHTML || route.endsWith(".html"))) {
599
+ const extractedLinks = await extractLinks(
600
+ dataBuff.toString("utf8"),
601
+ route,
602
+ res,
603
+ nitro.options.prerender.crawlLinks
1017
604
  );
1018
- tsConfig.compilerOptions.paths[alias] = [...new Set(paths)];
605
+ for (const _link of extractedLinks) {
606
+ if (canPrerender(_link)) {
607
+ routes.add(_link);
608
+ }
609
+ }
1019
610
  }
1020
- tsConfig.include = [
1021
- ...new Set(
1022
- tsConfig.include.map(
1023
- (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
1024
- )
1025
- )
1026
- ];
1027
- if (tsConfig.exclude) {
1028
- tsConfig.exclude = [
1029
- ...new Set(
1030
- tsConfig.exclude.map(
1031
- (p) => isAbsolute(p) ? relativeWithDot(tsconfigDir, p) : p
1032
- )
1033
- )
1034
- ];
611
+ await nitro.hooks.callHook("prerender:route", _route);
612
+ nitro.logger.log(formatPrerenderRoute(_route));
613
+ dataBuff = void 0;
614
+ return _route;
615
+ };
616
+ nitro.logger.info(
617
+ nitro.options.prerender.crawlLinks ? `Prerendering ${routes.size} initial routes with crawler` : `Prerendering ${routes.size} routes`
618
+ );
619
+ await runParallel(routes, generateRoute, {
620
+ concurrency: nitro.options.prerender.concurrency,
621
+ interval: nitro.options.prerender.interval
622
+ });
623
+ await closePrerenderer();
624
+ await nitro.hooks.callHook("prerender:done", {
625
+ prerenderedRoutes: nitro._prerenderedRoutes,
626
+ failedRoutes: [...failedRoutes]
627
+ });
628
+ if (nitro.options.prerender.failOnError && failedRoutes.size > 0) {
629
+ nitro.logger.log("\nErrors prerendering:");
630
+ for (const route of failedRoutes) {
631
+ const parents = linkParents.get(route.route);
632
+ parents?.size ? `
633
+ ${[...parents.values()].map((link) => colors.gray(` \u2502 \u2514\u2500\u2500 Linked from ${link}`)).join("\n")}` : "";
634
+ nitro.logger.log(formatPrerenderRoute(route));
1035
635
  }
1036
- types.tsConfig = tsConfig;
1037
- buildFiles.push({
1038
- path: tsConfigPath,
1039
- contents: () => JSON.stringify(tsConfig, null, 2)
1040
- });
636
+ nitro.logger.log("");
637
+ throw new Error("Exiting due to prerender errors.");
1041
638
  }
1042
- await nitro.hooks.callHook("types:extend", types);
1043
- await Promise.all(
1044
- buildFiles.map(async (file) => {
1045
- await writeFile(
1046
- resolve(nitro.options.buildDir, file.path),
1047
- typeof file.contents === "string" ? file.contents : file.contents()
1048
- );
1049
- })
639
+ const prerenderTimeInMs = Date.now() - prerenderStartTime;
640
+ nitro.logger.info(
641
+ `Prerendered ${nitro._prerenderedRoutes.length} routes in ${prerenderTimeInMs / 1e3} seconds`
1050
642
  );
1051
- }
1052
- const RELATIVE_RE = /^\.{1,2}\//;
1053
- function relativeWithDot(from, to) {
1054
- const rel = relative(from, to);
1055
- return RELATIVE_RE.test(rel) ? rel : "./" + rel;
643
+ if (nitro.options.compressPublicAssets) {
644
+ await compressPublicAssets(nitro);
645
+ }
1056
646
  }
1057
647
 
1058
648
  export { build as b, prerender as p, runParallel as r, writeTypes as w };