@useavalon/avalon 0.1.0
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.
- package/README.md +54 -0
- package/mod.ts +301 -0
- package/package.json +85 -0
- package/src/build/README.md +310 -0
- package/src/build/integration-bundler-plugin.ts +116 -0
- package/src/build/integration-config.ts +168 -0
- package/src/build/integration-detection-plugin.ts +117 -0
- package/src/build/integration-resolver-plugin.ts +90 -0
- package/src/build/island-manifest.ts +269 -0
- package/src/build/island-types-generator.ts +476 -0
- package/src/build/mdx-island-transform.ts +464 -0
- package/src/build/mdx-plugin.ts +98 -0
- package/src/build/page-island-transform.ts +598 -0
- package/src/build/prop-extractors/index.ts +21 -0
- package/src/build/prop-extractors/lit.ts +140 -0
- package/src/build/prop-extractors/qwik.ts +16 -0
- package/src/build/prop-extractors/solid.ts +125 -0
- package/src/build/prop-extractors/svelte.ts +194 -0
- package/src/build/prop-extractors/vue.ts +111 -0
- package/src/build/sidecar-file-manager.ts +104 -0
- package/src/build/sidecar-renderer.ts +30 -0
- package/src/client/adapters/index.ts +13 -0
- package/src/client/adapters/lit-adapter.ts +654 -0
- package/src/client/adapters/preact-adapter.ts +331 -0
- package/src/client/adapters/qwik-adapter.ts +345 -0
- package/src/client/adapters/react-adapter.ts +353 -0
- package/src/client/adapters/solid-adapter.ts +451 -0
- package/src/client/adapters/svelte-adapter.ts +524 -0
- package/src/client/adapters/vue-adapter.ts +467 -0
- package/src/client/components.ts +35 -0
- package/src/client/css-hmr-handler.ts +344 -0
- package/src/client/framework-adapter.ts +462 -0
- package/src/client/hmr-coordinator.ts +396 -0
- package/src/client/hmr-error-overlay.js +533 -0
- package/src/client/main.js +816 -0
- package/src/client/tests/css-hmr-handler.test.ts +360 -0
- package/src/client/tests/framework-adapter.test.ts +519 -0
- package/src/client/tests/hmr-coordinator.test.ts +176 -0
- package/src/client/tests/hydration-option-parsing.test.ts +107 -0
- package/src/client/tests/lit-adapter.test.ts +427 -0
- package/src/client/tests/preact-adapter.test.ts +353 -0
- package/src/client/tests/qwik-adapter.test.ts +343 -0
- package/src/client/tests/react-adapter.test.ts +317 -0
- package/src/client/tests/solid-adapter.test.ts +396 -0
- package/src/client/tests/svelte-adapter.test.ts +387 -0
- package/src/client/tests/vue-adapter.test.ts +407 -0
- package/src/client/types/framework-runtime.d.ts +68 -0
- package/src/client/types/vite-hmr.d.ts +46 -0
- package/src/client/types/vite-virtual-modules.d.ts +60 -0
- package/src/components/Image.tsx +123 -0
- package/src/components/IslandErrorBoundary.tsx +145 -0
- package/src/components/LayoutDataErrorBoundary.tsx +141 -0
- package/src/components/LayoutErrorBoundary.tsx +127 -0
- package/src/components/PersistentIsland.tsx +52 -0
- package/src/components/StreamingErrorBoundary.tsx +233 -0
- package/src/components/StreamingLayout.tsx +538 -0
- package/src/components/tests/component-analyzer.test.ts +96 -0
- package/src/components/tests/component-detection.test.ts +347 -0
- package/src/components/tests/persistent-islands.test.ts +398 -0
- package/src/core/components/component-analyzer.ts +192 -0
- package/src/core/components/component-detection.ts +508 -0
- package/src/core/components/enhanced-framework-detector.ts +500 -0
- package/src/core/components/framework-registry.ts +563 -0
- package/src/core/components/tests/enhanced-framework-detector.test.ts +577 -0
- package/src/core/components/tests/framework-registry.test.ts +465 -0
- package/src/core/content/mdx-processor.ts +46 -0
- package/src/core/integrations/README.md +282 -0
- package/src/core/integrations/index.ts +19 -0
- package/src/core/integrations/loader.ts +125 -0
- package/src/core/integrations/registry.ts +195 -0
- package/src/core/islands/island-persistence.ts +325 -0
- package/src/core/islands/island-state-serializer.ts +258 -0
- package/src/core/islands/persistent-island-context.tsx +80 -0
- package/src/core/islands/use-persistent-state.ts +68 -0
- package/src/core/layout/enhanced-layout-resolver.ts +322 -0
- package/src/core/layout/layout-cache-manager.ts +485 -0
- package/src/core/layout/layout-composer.ts +357 -0
- package/src/core/layout/layout-data-loader.ts +516 -0
- package/src/core/layout/layout-discovery.ts +243 -0
- package/src/core/layout/layout-matcher.ts +299 -0
- package/src/core/layout/layout-types.ts +110 -0
- package/src/core/layout/tests/enhanced-layout-resolver.test.ts +477 -0
- package/src/core/layout/tests/layout-cache-optimization.test.ts +149 -0
- package/src/core/layout/tests/layout-composer.test.ts +486 -0
- package/src/core/layout/tests/layout-data-loader.test.ts +443 -0
- package/src/core/layout/tests/layout-discovery.test.ts +253 -0
- package/src/core/layout/tests/layout-matcher.test.ts +480 -0
- package/src/core/modules/framework-module-resolver.ts +273 -0
- package/src/core/modules/tests/framework-module-resolver.test.ts +263 -0
- package/src/core/modules/tests/module-resolution-integration.test.ts +117 -0
- package/src/islands/component-analysis.ts +213 -0
- package/src/islands/css-utils.ts +565 -0
- package/src/islands/discovery/index.ts +80 -0
- package/src/islands/discovery/registry.ts +340 -0
- package/src/islands/discovery/resolver.ts +477 -0
- package/src/islands/discovery/scanner.ts +386 -0
- package/src/islands/discovery/tests/island-discovery.test.ts +881 -0
- package/src/islands/discovery/types.ts +117 -0
- package/src/islands/discovery/validator.ts +544 -0
- package/src/islands/discovery/watcher.ts +368 -0
- package/src/islands/framework-detection.ts +428 -0
- package/src/islands/integration-loader.ts +490 -0
- package/src/islands/island.tsx +565 -0
- package/src/islands/render-cache.ts +550 -0
- package/src/islands/types.ts +80 -0
- package/src/islands/universal-css-collector.ts +157 -0
- package/src/islands/universal-head-collector.ts +137 -0
- package/src/layout-system.d.ts +592 -0
- package/src/layout-system.ts +218 -0
- package/src/middleware/__tests__/discovery.test.ts +107 -0
- package/src/middleware/discovery.ts +268 -0
- package/src/middleware/executor.ts +315 -0
- package/src/middleware/index.ts +76 -0
- package/src/middleware/types.ts +99 -0
- package/src/nitro/build-config.ts +576 -0
- package/src/nitro/config.ts +483 -0
- package/src/nitro/error-handler.ts +636 -0
- package/src/nitro/index.ts +173 -0
- package/src/nitro/island-manifest.ts +584 -0
- package/src/nitro/middleware-adapter.ts +260 -0
- package/src/nitro/renderer.ts +1458 -0
- package/src/nitro/route-discovery.ts +439 -0
- package/src/nitro/types.ts +321 -0
- package/src/render/collect-css.ts +198 -0
- package/src/render/error-pages.ts +79 -0
- package/src/render/isolated-ssr-renderer.ts +654 -0
- package/src/render/ssr.ts +1030 -0
- package/src/schemas/api.ts +30 -0
- package/src/schemas/core.ts +64 -0
- package/src/schemas/index.ts +212 -0
- package/src/schemas/layout.ts +279 -0
- package/src/schemas/routing/index.ts +38 -0
- package/src/schemas/routing.ts +376 -0
- package/src/types/as-island.ts +20 -0
- package/src/types/image.d.ts +106 -0
- package/src/types/index.d.ts +22 -0
- package/src/types/island-jsx.d.ts +33 -0
- package/src/types/island-prop.d.ts +20 -0
- package/src/types/layout.ts +285 -0
- package/src/types/mdx.d.ts +6 -0
- package/src/types/routing.ts +555 -0
- package/src/types/tests/layout-types.test.ts +197 -0
- package/src/types/types.ts +5 -0
- package/src/types/urlpattern.d.ts +49 -0
- package/src/types/vite-env.d.ts +11 -0
- package/src/utils/dev-logger.ts +299 -0
- package/src/utils/fs.ts +151 -0
- package/src/vite-plugin/auto-discover.ts +551 -0
- package/src/vite-plugin/config.ts +266 -0
- package/src/vite-plugin/errors.ts +127 -0
- package/src/vite-plugin/image-optimization.ts +151 -0
- package/src/vite-plugin/integration-activator.ts +126 -0
- package/src/vite-plugin/island-sidecar-plugin.ts +176 -0
- package/src/vite-plugin/module-discovery.ts +189 -0
- package/src/vite-plugin/nitro-integration.ts +1334 -0
- package/src/vite-plugin/plugin.ts +329 -0
- package/src/vite-plugin/tests/image-optimization.test.ts +54 -0
- package/src/vite-plugin/types.ts +327 -0
- package/src/vite-plugin/validation.ts +228 -0
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nitro Configuration Module for Avalon
|
|
3
|
+
*
|
|
4
|
+
* This module provides configuration interfaces and utilities for integrating
|
|
5
|
+
* Nitro as Avalon's server runtime. It handles preset configuration, route rules,
|
|
6
|
+
* and merging Avalon-specific options with Nitro defaults.
|
|
7
|
+
*
|
|
8
|
+
* ## Static Asset Handling
|
|
9
|
+
*
|
|
10
|
+
* Nitro automatically serves static assets from the `public/` directory at the root path.
|
|
11
|
+
* The configuration supports:
|
|
12
|
+
* - `publicAssets`: Configures directories for static file serving
|
|
13
|
+
* - `routeRules`: Configures cache headers for different asset types
|
|
14
|
+
* - `staticAssets`: Avalon-specific static asset configuration
|
|
15
|
+
*
|
|
16
|
+
* Default route rules for static assets are generated by `createDefaultStaticAssetRouteRules()`:
|
|
17
|
+
* - `/assets/**`, `/islands/**`, `/chunks/**`: Long cache (1 year, immutable)
|
|
18
|
+
* - `/*.woff`, `/*.woff2`: Long cache for fonts
|
|
19
|
+
* - `/*.html`, `/*.css`: Short cache with revalidation
|
|
20
|
+
* - `/favicon.ico`: Medium cache (1 day)
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { ResolvedAvalonConfig } from "../vite-plugin/types.ts";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Cache configuration options for route rules
|
|
27
|
+
*/
|
|
28
|
+
export interface CacheOptions {
|
|
29
|
+
/** Maximum age in seconds for cache validity */
|
|
30
|
+
maxAge?: number;
|
|
31
|
+
/** Maximum age in seconds for stale content */
|
|
32
|
+
staleMaxAge?: number;
|
|
33
|
+
/** Enable stale-while-revalidate behavior */
|
|
34
|
+
swr?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Route rule configuration for caching, redirects, proxying, and headers
|
|
39
|
+
*/
|
|
40
|
+
export interface RouteRule {
|
|
41
|
+
/** Cache configuration or boolean to enable/disable */
|
|
42
|
+
cache?: CacheOptions | boolean;
|
|
43
|
+
/** Redirect destination URL */
|
|
44
|
+
redirect?: string;
|
|
45
|
+
/** Proxy destination URL */
|
|
46
|
+
proxy?: string;
|
|
47
|
+
/** Custom headers to set */
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
/** Enable CORS for this route */
|
|
50
|
+
cors?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Static asset serving configuration
|
|
55
|
+
*/
|
|
56
|
+
export interface StaticAssetsConfig {
|
|
57
|
+
/**
|
|
58
|
+
* Directory containing public static assets
|
|
59
|
+
* @default "public"
|
|
60
|
+
*/
|
|
61
|
+
publicDir?: string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Directory containing compiled build output
|
|
65
|
+
* @default "dist"
|
|
66
|
+
*/
|
|
67
|
+
buildDir?: string;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Enable serving pre-compressed assets (gzip, brotli)
|
|
71
|
+
* @default true
|
|
72
|
+
*/
|
|
73
|
+
compression?: boolean;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Default cache control header for immutable static assets
|
|
77
|
+
* @default "public, max-age=31536000, immutable"
|
|
78
|
+
*/
|
|
79
|
+
cacheControl?: string;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Cache control header for mutable assets (HTML, etc.)
|
|
83
|
+
* @default "public, max-age=0, must-revalidate"
|
|
84
|
+
*/
|
|
85
|
+
mutableCacheControl?: string;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Custom headers to add to all static asset responses
|
|
89
|
+
*/
|
|
90
|
+
headers?: Record<string, string>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Avalon-specific Nitro configuration options
|
|
95
|
+
*/
|
|
96
|
+
export interface AvalonNitroConfig {
|
|
97
|
+
/**
|
|
98
|
+
* Deployment preset (vercel, cloudflare, deno-deploy, node-server, netlify, etc.)
|
|
99
|
+
* @default "node-server"
|
|
100
|
+
*/
|
|
101
|
+
preset?: string;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Directory containing server routes
|
|
105
|
+
* @default "server"
|
|
106
|
+
*/
|
|
107
|
+
serverDir?: string;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Directory containing pages (overrides Avalon config if set)
|
|
111
|
+
*/
|
|
112
|
+
pagesDir?: string;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Enable streaming SSR responses
|
|
116
|
+
* @default true
|
|
117
|
+
*/
|
|
118
|
+
streaming?: boolean;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Route rules for caching, redirects, proxying, and headers
|
|
122
|
+
* Keys are route patterns (e.g., "/api/**", "/static/**")
|
|
123
|
+
*/
|
|
124
|
+
routeRules?: Record<string, RouteRule>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Runtime configuration accessible via useRuntimeConfig()
|
|
128
|
+
* Can be overridden by NITRO_ prefixed environment variables
|
|
129
|
+
*/
|
|
130
|
+
runtimeConfig?: Record<string, unknown>;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Public runtime configuration (exposed to client)
|
|
134
|
+
*/
|
|
135
|
+
publicRuntimeConfig?: Record<string, unknown>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Static asset serving configuration
|
|
139
|
+
*/
|
|
140
|
+
staticAssets?: StaticAssetsConfig;
|
|
141
|
+
|
|
142
|
+
/** Nitro v3: Compatibility date for preset features (YYYY-MM-DD) */
|
|
143
|
+
compatibilityDate?: string;
|
|
144
|
+
/** Nitro v3: Dependencies to trace instead of bundle */
|
|
145
|
+
traceDeps?: string[];
|
|
146
|
+
/** Nitro v3: Rolldown-specific configuration */
|
|
147
|
+
rolldownConfig?: Record<string, unknown>;
|
|
148
|
+
/** Nitro v3: Custom server entry point */
|
|
149
|
+
serverEntry?: string;
|
|
150
|
+
/** Nitro v3: Renderer configuration, or false to disable */
|
|
151
|
+
renderer?: { handler: string } | false;
|
|
152
|
+
/** Nitro v3: Pre-compress public assets (gzip, brotli, zstd) */
|
|
153
|
+
compressPublicAssets?: boolean | { gzip?: boolean; brotli?: boolean; zstd?: boolean };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Nitro configuration output structure
|
|
158
|
+
* This matches the expected NitroConfig interface from nitro/types
|
|
159
|
+
*/
|
|
160
|
+
export interface NitroConfigOutput {
|
|
161
|
+
/** Deployment preset */
|
|
162
|
+
preset: string;
|
|
163
|
+
/** Server directory */
|
|
164
|
+
serverDir: string;
|
|
165
|
+
/** Route rules */
|
|
166
|
+
routeRules: Record<string, RouteRule>;
|
|
167
|
+
/** Runtime configuration */
|
|
168
|
+
runtimeConfig: {
|
|
169
|
+
avalon: AvalonRuntimeConfig;
|
|
170
|
+
[key: string]: unknown;
|
|
171
|
+
};
|
|
172
|
+
/** Public runtime configuration */
|
|
173
|
+
publicRuntimeConfig?: Record<string, unknown>;
|
|
174
|
+
/** Renderer configuration, or false to disable */
|
|
175
|
+
renderer?: {
|
|
176
|
+
handler: string;
|
|
177
|
+
} | false;
|
|
178
|
+
/** Nitro v3: Compatibility date for preset features (YYYY-MM-DD) */
|
|
179
|
+
compatibilityDate?: string;
|
|
180
|
+
/** Nitro v3: Dependencies to trace instead of bundle */
|
|
181
|
+
traceDeps?: string[];
|
|
182
|
+
/** Nitro v3: Rolldown-specific configuration */
|
|
183
|
+
rolldownConfig?: Record<string, unknown>;
|
|
184
|
+
/** Nitro v3: Custom server entry point */
|
|
185
|
+
serverEntry?: string;
|
|
186
|
+
/** Nitro v3: Pre-compress public assets (gzip, brotli, zstd) */
|
|
187
|
+
compressPublicAssets?: boolean | { gzip?: boolean; brotli?: boolean; zstd?: boolean };
|
|
188
|
+
/** Public assets directory */
|
|
189
|
+
publicAssets?: Array<{
|
|
190
|
+
dir: string;
|
|
191
|
+
baseURL?: string;
|
|
192
|
+
maxAge?: number;
|
|
193
|
+
}>;
|
|
194
|
+
/** Server assets configuration */
|
|
195
|
+
serverAssets?: Array<{
|
|
196
|
+
baseName: string;
|
|
197
|
+
dir: string;
|
|
198
|
+
}>;
|
|
199
|
+
/** Static assets configuration */
|
|
200
|
+
staticAssets?: StaticAssetsConfig;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Avalon-specific runtime configuration stored in Nitro's runtimeConfig
|
|
205
|
+
*/
|
|
206
|
+
export interface AvalonRuntimeConfig {
|
|
207
|
+
/** Enable streaming SSR */
|
|
208
|
+
streaming: boolean;
|
|
209
|
+
/** Pages directory path */
|
|
210
|
+
pagesDir: string;
|
|
211
|
+
/** Layouts directory path */
|
|
212
|
+
layoutsDir: string;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Default static assets configuration
|
|
217
|
+
*/
|
|
218
|
+
export const DEFAULT_STATIC_ASSETS_CONFIG: Required<StaticAssetsConfig> = {
|
|
219
|
+
publicDir: "public",
|
|
220
|
+
buildDir: "dist",
|
|
221
|
+
compression: true,
|
|
222
|
+
cacheControl: "public, max-age=31536000, immutable",
|
|
223
|
+
mutableCacheControl: "public, max-age=0, must-revalidate",
|
|
224
|
+
headers: {},
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* All valid Nitro v3 preset names (underscore convention).
|
|
229
|
+
*/
|
|
230
|
+
export const VALID_V3_PRESETS: string[] = [
|
|
231
|
+
"node_server",
|
|
232
|
+
"node_middleware",
|
|
233
|
+
"vercel",
|
|
234
|
+
"cloudflare_module",
|
|
235
|
+
"cloudflare_pages",
|
|
236
|
+
"deno_deploy",
|
|
237
|
+
"deno_server",
|
|
238
|
+
"netlify_functions",
|
|
239
|
+
"netlify_edge",
|
|
240
|
+
"aws_lambda",
|
|
241
|
+
"azure_swa",
|
|
242
|
+
"firebase_functions",
|
|
243
|
+
"render_com",
|
|
244
|
+
"static",
|
|
245
|
+
"browser",
|
|
246
|
+
];
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Validates a preset name against the v3 preset list.
|
|
250
|
+
* Returns the preset name if valid, throws if unrecognized.
|
|
251
|
+
*
|
|
252
|
+
* @param preset - The preset name to validate (must be a v3 name)
|
|
253
|
+
* @returns The validated v3 preset name
|
|
254
|
+
* @throws Error if the preset is not recognized
|
|
255
|
+
*/
|
|
256
|
+
export function resolvePresetName(preset: string): string {
|
|
257
|
+
if (VALID_V3_PRESETS.includes(preset)) return preset;
|
|
258
|
+
throw new Error(
|
|
259
|
+
`Unknown Nitro preset: "${preset}". Valid presets: ${VALID_V3_PRESETS.join(", ")}`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Default Nitro configuration values
|
|
265
|
+
*/
|
|
266
|
+
export const DEFAULT_NITRO_CONFIG: Required<
|
|
267
|
+
Pick<AvalonNitroConfig, "preset" | "serverDir" | "streaming">
|
|
268
|
+
> = {
|
|
269
|
+
preset: "node_server",
|
|
270
|
+
serverDir: "server",
|
|
271
|
+
streaming: true,
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Creates a Nitro configuration from Avalon plugin config and Nitro-specific options
|
|
276
|
+
*
|
|
277
|
+
* This function merges Avalon's resolved configuration with Nitro-specific options
|
|
278
|
+
* to produce a complete Nitro configuration object. Avalon-specific settings are
|
|
279
|
+
* stored in `runtimeConfig.avalon` for access by handlers.
|
|
280
|
+
*
|
|
281
|
+
* @param avalonNitroConfig - Nitro-specific configuration options
|
|
282
|
+
* @param resolvedAvalonConfig - Resolved Avalon plugin configuration
|
|
283
|
+
* @returns Complete Nitro configuration object
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```ts
|
|
287
|
+
* const nitroConfig = createNitroConfig(
|
|
288
|
+
* { preset: 'vercel', streaming: true },
|
|
289
|
+
* resolvedAvalonConfig
|
|
290
|
+
* );
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
export function createNitroConfig(
|
|
294
|
+
avalonNitroConfig: AvalonNitroConfig,
|
|
295
|
+
resolvedAvalonConfig: ResolvedAvalonConfig
|
|
296
|
+
): NitroConfigOutput {
|
|
297
|
+
// Determine final directory paths (Nitro config overrides Avalon config)
|
|
298
|
+
const pagesDir = avalonNitroConfig.pagesDir ?? resolvedAvalonConfig.pagesDir;
|
|
299
|
+
const layoutsDir = resolvedAvalonConfig.layoutsDir;
|
|
300
|
+
|
|
301
|
+
// Build Avalon runtime config
|
|
302
|
+
const avalonRuntimeConfig: AvalonRuntimeConfig = {
|
|
303
|
+
streaming: avalonNitroConfig.streaming ?? DEFAULT_NITRO_CONFIG.streaming,
|
|
304
|
+
pagesDir,
|
|
305
|
+
layoutsDir,
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
// Validate that runtimeConfig does not contain a 'nitro' key (reserved in v3)
|
|
309
|
+
if (avalonNitroConfig.runtimeConfig && "nitro" in avalonNitroConfig.runtimeConfig) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
'The "nitro" key in runtimeConfig is reserved by Nitro v3 and cannot be used.'
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Merge user runtime config with Avalon runtime config
|
|
316
|
+
const runtimeConfig: NitroConfigOutput["runtimeConfig"] = {
|
|
317
|
+
avalon: avalonRuntimeConfig,
|
|
318
|
+
...avalonNitroConfig.runtimeConfig,
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// Merge static assets config with defaults
|
|
322
|
+
const staticAssetsConfig: StaticAssetsConfig = {
|
|
323
|
+
...DEFAULT_STATIC_ASSETS_CONFIG,
|
|
324
|
+
...avalonNitroConfig.staticAssets,
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// Create default route rules for static assets
|
|
328
|
+
const defaultStaticRouteRules = createDefaultStaticAssetRouteRules(staticAssetsConfig);
|
|
329
|
+
|
|
330
|
+
// Merge user route rules with default static asset rules
|
|
331
|
+
const routeRules = mergeRouteRules(
|
|
332
|
+
defaultStaticRouteRules,
|
|
333
|
+
avalonNitroConfig.routeRules ?? {}
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
// Configure public assets directories
|
|
337
|
+
const publicAssets: NitroConfigOutput["publicAssets"] = [
|
|
338
|
+
{
|
|
339
|
+
dir: staticAssetsConfig.publicDir ?? DEFAULT_STATIC_ASSETS_CONFIG.publicDir,
|
|
340
|
+
baseURL: "/",
|
|
341
|
+
maxAge: 0, // Let route rules handle caching
|
|
342
|
+
},
|
|
343
|
+
];
|
|
344
|
+
|
|
345
|
+
// Resolve renderer: support explicit false to disable, otherwise use default handler
|
|
346
|
+
const renderer: NitroConfigOutput["renderer"] =
|
|
347
|
+
avalonNitroConfig.renderer === false
|
|
348
|
+
? false
|
|
349
|
+
: (avalonNitroConfig.renderer ?? { handler: "./server/renderer.ts" });
|
|
350
|
+
|
|
351
|
+
return {
|
|
352
|
+
preset: resolvePresetName(avalonNitroConfig.preset ?? DEFAULT_NITRO_CONFIG.preset),
|
|
353
|
+
serverDir: avalonNitroConfig.serverDir ?? DEFAULT_NITRO_CONFIG.serverDir,
|
|
354
|
+
routeRules,
|
|
355
|
+
runtimeConfig,
|
|
356
|
+
publicRuntimeConfig: avalonNitroConfig.publicRuntimeConfig,
|
|
357
|
+
renderer,
|
|
358
|
+
compatibilityDate: avalonNitroConfig.compatibilityDate,
|
|
359
|
+
traceDeps: avalonNitroConfig.traceDeps,
|
|
360
|
+
rolldownConfig: avalonNitroConfig.rolldownConfig,
|
|
361
|
+
serverEntry: avalonNitroConfig.serverEntry,
|
|
362
|
+
compressPublicAssets: avalonNitroConfig.compressPublicAssets,
|
|
363
|
+
publicAssets,
|
|
364
|
+
staticAssets: staticAssetsConfig,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Creates default route rules for static asset caching
|
|
370
|
+
*
|
|
371
|
+
* @param config - Static assets configuration
|
|
372
|
+
* @returns Route rules for static assets
|
|
373
|
+
*/
|
|
374
|
+
export function createDefaultStaticAssetRouteRules(
|
|
375
|
+
config: StaticAssetsConfig
|
|
376
|
+
): Record<string, RouteRule> {
|
|
377
|
+
const cacheControl = config.cacheControl ?? DEFAULT_STATIC_ASSETS_CONFIG.cacheControl;
|
|
378
|
+
const mutableCacheControl = config.mutableCacheControl ?? DEFAULT_STATIC_ASSETS_CONFIG.mutableCacheControl;
|
|
379
|
+
|
|
380
|
+
return {
|
|
381
|
+
// Immutable assets with hashed filenames (long cache)
|
|
382
|
+
"/assets/**": {
|
|
383
|
+
headers: {
|
|
384
|
+
"Cache-Control": cacheControl,
|
|
385
|
+
...config.headers,
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
"/islands/**": {
|
|
389
|
+
headers: {
|
|
390
|
+
"Cache-Control": cacheControl,
|
|
391
|
+
...config.headers,
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
"/chunks/**": {
|
|
395
|
+
headers: {
|
|
396
|
+
"Cache-Control": cacheControl,
|
|
397
|
+
...config.headers,
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
"/_nuxt/**": {
|
|
401
|
+
headers: {
|
|
402
|
+
"Cache-Control": cacheControl,
|
|
403
|
+
...config.headers,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
// Font files (long cache)
|
|
407
|
+
"/**/*.woff": {
|
|
408
|
+
headers: {
|
|
409
|
+
"Cache-Control": cacheControl,
|
|
410
|
+
...config.headers,
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
"/**/*.woff2": {
|
|
414
|
+
headers: {
|
|
415
|
+
"Cache-Control": cacheControl,
|
|
416
|
+
...config.headers,
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
// Mutable assets (short cache with revalidation)
|
|
420
|
+
"/**/*.html": {
|
|
421
|
+
headers: {
|
|
422
|
+
"Cache-Control": mutableCacheControl,
|
|
423
|
+
...config.headers,
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
// Favicon (medium cache)
|
|
427
|
+
"/favicon.ico": {
|
|
428
|
+
headers: {
|
|
429
|
+
"Cache-Control": "public, max-age=86400",
|
|
430
|
+
...config.headers,
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
// CSS files in public directory (may be mutable)
|
|
434
|
+
"/**/*.css": {
|
|
435
|
+
headers: {
|
|
436
|
+
"Cache-Control": mutableCacheControl,
|
|
437
|
+
...config.headers,
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Validates a Nitro preset name against the v3 preset list
|
|
445
|
+
*
|
|
446
|
+
* @param preset - The preset name to validate
|
|
447
|
+
* @returns True if the preset is a known valid v3 preset
|
|
448
|
+
*/
|
|
449
|
+
export function isValidPreset(preset: string): boolean {
|
|
450
|
+
return VALID_V3_PRESETS.includes(preset);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Merges route rules, with later rules taking precedence
|
|
455
|
+
*
|
|
456
|
+
* @param baseRules - Base route rules
|
|
457
|
+
* @param overrideRules - Override route rules
|
|
458
|
+
* @returns Merged route rules
|
|
459
|
+
*/
|
|
460
|
+
export function mergeRouteRules(
|
|
461
|
+
baseRules: Record<string, RouteRule>,
|
|
462
|
+
overrideRules: Record<string, RouteRule>
|
|
463
|
+
): Record<string, RouteRule> {
|
|
464
|
+
const merged: Record<string, RouteRule> = { ...baseRules };
|
|
465
|
+
|
|
466
|
+
for (const [pattern, rule] of Object.entries(overrideRules)) {
|
|
467
|
+
if (merged[pattern]) {
|
|
468
|
+
// Deep merge the rule
|
|
469
|
+
merged[pattern] = {
|
|
470
|
+
...merged[pattern],
|
|
471
|
+
...rule,
|
|
472
|
+
headers: {
|
|
473
|
+
...merged[pattern].headers,
|
|
474
|
+
...rule.headers,
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
} else {
|
|
478
|
+
merged[pattern] = rule;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return merged;
|
|
483
|
+
}
|