@useavalon/avalon 0.1.22 → 0.1.24
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/dist/mod.d.ts +50 -0
- package/dist/src/build/integration-bundler-plugin.d.ts +25 -0
- package/dist/src/build/integration-config.d.ts +44 -0
- package/dist/src/build/integration-detection-plugin.d.ts +20 -0
- package/dist/src/build/integration-resolver-plugin.d.ts +10 -0
- package/dist/src/build/island-manifest.d.ts +57 -0
- package/dist/src/build/island-types-generator.d.ts +49 -0
- package/dist/src/build/mdx-island-transform.d.ts +23 -0
- package/dist/src/build/mdx-plugin.d.ts +36 -0
- package/dist/src/build/page-island-transform.d.ts +41 -0
- package/dist/src/build/prop-extractors/index.d.ts +8 -0
- package/dist/src/build/prop-extractors/lit.d.ts +11 -0
- package/dist/src/build/prop-extractors/qwik.d.ts +9 -0
- package/dist/src/build/prop-extractors/solid.d.ts +12 -0
- package/dist/src/build/prop-extractors/svelte.d.ts +13 -0
- package/dist/src/build/prop-extractors/vue.d.ts +19 -0
- package/dist/src/build/sidecar-file-manager.d.ts +23 -0
- package/dist/src/build/sidecar-renderer.d.ts +22 -0
- package/dist/src/client/adapters/index.d.ts +15 -0
- package/dist/src/client/components.d.ts +21 -0
- package/dist/src/client/css-hmr-handler.d.ts +94 -0
- package/dist/src/client/framework-adapter.d.ts +225 -0
- package/dist/src/client/hmr-coordinator.d.ts +88 -0
- package/dist/src/components/Image.d.ts +61 -0
- package/dist/src/components/IslandErrorBoundary.d.ts +37 -0
- package/dist/src/components/IslandErrorBoundary.js +1 -1
- package/dist/src/components/LayoutDataErrorBoundary.d.ts +34 -0
- package/dist/src/components/LayoutDataErrorBoundary.js +1 -1
- package/dist/src/components/LayoutErrorBoundary.d.ts +25 -0
- package/dist/src/components/LayoutErrorBoundary.js +1 -1
- package/dist/src/components/PersistentIsland.d.ts +36 -0
- package/dist/src/components/StreamingErrorBoundary.d.ts +42 -0
- package/dist/src/components/StreamingErrorBoundary.js +1 -1
- package/dist/src/components/StreamingLayout.d.ts +83 -0
- package/dist/src/components/StreamingLayout.js +1 -1
- package/dist/src/core/components/component-analyzer.d.ts +48 -0
- package/dist/src/core/components/component-detection.d.ts +72 -0
- package/dist/src/core/components/enhanced-framework-detector.d.ts +78 -0
- package/dist/src/core/components/framework-registry.d.ts +114 -0
- package/dist/src/core/content/mdx-processor.d.ts +14 -0
- package/dist/src/core/integrations/index.d.ts +6 -0
- package/dist/src/core/integrations/loader.d.ts +35 -0
- package/dist/src/core/integrations/registry.d.ts +51 -0
- package/dist/src/core/islands/island-persistence.d.ts +74 -0
- package/dist/src/core/islands/island-state-serializer.d.ts +53 -0
- package/dist/src/core/islands/persistent-island-context.d.ts +36 -0
- package/dist/src/core/islands/use-persistent-state.d.ts +17 -0
- package/dist/src/core/layout/enhanced-layout-resolver.d.ts +73 -0
- package/dist/src/core/layout/layout-cache-manager.d.ts +66 -0
- package/dist/src/core/layout/layout-composer.d.ts +63 -0
- package/dist/src/core/layout/layout-data-loader.d.ts +146 -0
- package/dist/src/core/layout/layout-discovery.d.ts +51 -0
- package/dist/src/core/layout/layout-matcher.d.ts +77 -0
- package/dist/src/core/layout/layout-types.d.ts +94 -0
- package/dist/src/core/modules/framework-module-resolver.d.ts +85 -0
- package/dist/src/islands/component-analysis.d.ts +38 -0
- package/dist/src/islands/css-utils.d.ts +81 -0
- package/dist/src/islands/discovery/index.d.ts +16 -0
- package/dist/src/islands/discovery/registry.d.ts +141 -0
- package/dist/src/islands/discovery/resolver.d.ts +190 -0
- package/dist/src/islands/discovery/scanner.d.ts +55 -0
- package/dist/src/islands/discovery/types.d.ts +92 -0
- package/dist/src/islands/discovery/validator.d.ts +89 -0
- package/dist/src/islands/discovery/watcher.d.ts +95 -0
- package/dist/src/islands/framework-detection.d.ts +53 -0
- package/dist/src/islands/integration-loader.d.ts +139 -0
- package/dist/src/islands/island.d.ts +55 -0
- package/dist/src/islands/render-cache.d.ts +203 -0
- package/dist/src/islands/types.d.ts +63 -0
- package/dist/src/islands/universal-css-collector.d.ts +41 -0
- package/dist/src/islands/universal-head-collector.d.ts +42 -0
- package/dist/src/layout-system.d.ts +92 -592
- package/dist/src/middleware/discovery.d.ts +70 -0
- package/dist/src/middleware/executor.d.ts +52 -0
- package/dist/src/middleware/index.d.ts +43 -0
- package/dist/src/middleware/types.d.ts +89 -0
- package/dist/src/nitro/build-config.d.ts +163 -0
- package/dist/src/nitro/config.d.ts +268 -0
- package/dist/src/nitro/error-handler.d.ts +151 -0
- package/dist/src/nitro/index.d.ts +15 -0
- package/dist/src/nitro/island-manifest.d.ts +191 -0
- package/dist/src/nitro/middleware-adapter.d.ts +151 -0
- package/dist/src/nitro/renderer.d.ts +342 -0
- package/dist/src/nitro/route-discovery.d.ts +142 -0
- package/dist/src/nitro/types.d.ts +278 -0
- package/dist/src/render/collect-css.d.ts +28 -0
- package/dist/src/render/error-pages.d.ts +14 -0
- package/dist/src/render/isolated-ssr-renderer.d.ts +127 -0
- package/dist/src/render/ssr.d.ts +56 -0
- package/dist/src/schemas/api.d.ts +27 -0
- package/dist/src/schemas/core.d.ts +75 -0
- package/dist/src/schemas/index.d.ts +79 -0
- package/dist/src/schemas/index.js +1 -1
- package/dist/src/schemas/layout.d.ts +282 -0
- package/dist/src/schemas/routing/index.d.ts +181 -0
- package/dist/src/schemas/routing.d.ts +388 -0
- package/dist/src/types/as-island.d.ts +17 -0
- package/dist/src/types/layout.d.ts +177 -0
- package/dist/src/types/routing.d.ts +297 -0
- package/dist/src/types/types.d.ts +6 -0
- package/dist/src/utils/dev-logger.d.ts +84 -0
- package/dist/src/utils/fs.d.ts +41 -0
- package/dist/src/vite-plugin/auto-discover.d.ts +72 -0
- package/dist/src/vite-plugin/config.d.ts +82 -0
- package/dist/src/vite-plugin/errors.d.ts +62 -0
- package/dist/src/vite-plugin/image-optimization.d.ts +36 -0
- package/dist/src/vite-plugin/integration-activator.d.ts +48 -0
- package/dist/src/vite-plugin/island-sidecar-plugin.d.ts +17 -0
- package/dist/src/vite-plugin/module-discovery.d.ts +66 -0
- package/dist/src/vite-plugin/nitro-integration.d.ts +56 -0
- package/dist/src/vite-plugin/nitro-integration.js +1 -1
- package/dist/src/vite-plugin/plugin.d.ts +51 -0
- package/dist/src/vite-plugin/types.d.ts +281 -0
- package/dist/src/vite-plugin/validation.d.ts +93 -0
- package/package.json +33 -9
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration Activator for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module handles the activation of framework integrations based on
|
|
5
|
+
* the plugin configuration. It validates integration names and loads
|
|
6
|
+
* the appropriate integration packages.
|
|
7
|
+
*/
|
|
8
|
+
import type { IntegrationName, ResolvedAvalonConfig } from "./types.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Valid integration names that can be activated
|
|
11
|
+
* This array is used for validation and error messages
|
|
12
|
+
*/
|
|
13
|
+
export declare const VALID_INTEGRATION_NAMES: readonly IntegrationName[];
|
|
14
|
+
/**
|
|
15
|
+
* Check if a string is a valid integration name
|
|
16
|
+
*
|
|
17
|
+
* @param name - The name to validate
|
|
18
|
+
* @returns True if the name is a valid IntegrationName
|
|
19
|
+
*/
|
|
20
|
+
export declare function isValidIntegrationName(name: string): name is IntegrationName;
|
|
21
|
+
/**
|
|
22
|
+
* Activates the specified integrations
|
|
23
|
+
*
|
|
24
|
+
* Uses the existing integration loader and registry to load and activate
|
|
25
|
+
* framework integrations based on the configuration.
|
|
26
|
+
*
|
|
27
|
+
* @param config - The resolved Avalon configuration
|
|
28
|
+
* @param activeIntegrations - Set to track which integrations have been activated
|
|
29
|
+
* @throws IntegrationError if an invalid integration name is provided or loading fails
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* const activeIntegrations = new Set<IntegrationName>();
|
|
34
|
+
* await activateIntegrations(resolvedConfig, activeIntegrations);
|
|
35
|
+
* // activeIntegrations now contains all successfully loaded integrations
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function activateIntegrations(config: ResolvedAvalonConfig, activeIntegrations: Set<IntegrationName>): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Activate a single integration by name
|
|
41
|
+
*
|
|
42
|
+
* @param name - The integration name to activate
|
|
43
|
+
* @param activeIntegrations - Set to track which integrations have been activated
|
|
44
|
+
* @param verbose - Whether to log activation messages
|
|
45
|
+
* @returns True if the integration was activated, false if already active
|
|
46
|
+
* @throws IntegrationError if the name is invalid or loading fails
|
|
47
|
+
*/
|
|
48
|
+
export declare function activateSingleIntegration(name: string, activeIntegrations: Set<IntegrationName>, _verbose?: boolean): Promise<boolean>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
export interface SidecarPluginOptions {
|
|
3
|
+
/** Whether to log verbose output */
|
|
4
|
+
verbose?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Check tsconfig.json for `allowArbitraryExtensions` and warn if missing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function checkTsConfigForArbitraryExtensions(projectRoot: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Vite plugin that auto-generates `.d.[ext].ts` sidecar declaration files
|
|
12
|
+
* for non-React/Preact components when they are used as islands.
|
|
13
|
+
*
|
|
14
|
+
* Sidecars are generated on-demand when component files are loaded,
|
|
15
|
+
* rather than scanning a fixed directory at startup.
|
|
16
|
+
*/
|
|
17
|
+
export declare function islandSidecarPlugin(options?: SidecarPluginOptions): Plugin;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Discovery for Modular Architecture
|
|
3
|
+
*
|
|
4
|
+
* Discovers pages and layouts within feature modules for file-based routing.
|
|
5
|
+
* Supports co-located architecture where each module contains its own pages/layouts.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResolvedModulesConfig } from "./types.ts";
|
|
8
|
+
/**
|
|
9
|
+
* Discovered module with its pages and layouts directories
|
|
10
|
+
*/
|
|
11
|
+
export interface DiscoveredModule {
|
|
12
|
+
/** Module name (folder name) */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Absolute path to the module directory */
|
|
15
|
+
path: string;
|
|
16
|
+
/** Absolute path to pages directory (if exists) */
|
|
17
|
+
pagesDir: string | null;
|
|
18
|
+
/** Absolute path to layouts directory (if exists) */
|
|
19
|
+
layoutsDir: string | null;
|
|
20
|
+
/** Route prefix derived from module name */
|
|
21
|
+
routePrefix: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Result of module discovery
|
|
25
|
+
*/
|
|
26
|
+
export interface ModuleDiscoveryResult {
|
|
27
|
+
/** All discovered modules */
|
|
28
|
+
modules: DiscoveredModule[];
|
|
29
|
+
/** All page directories (for route discovery) */
|
|
30
|
+
pageDirs: Array<{
|
|
31
|
+
dir: string;
|
|
32
|
+
prefix: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** All layout directories */
|
|
35
|
+
layoutDirs: Array<{
|
|
36
|
+
dir: string;
|
|
37
|
+
prefix: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Discover all modules within the modules directory
|
|
42
|
+
*
|
|
43
|
+
* @param modulesConfig - Resolved modules configuration
|
|
44
|
+
* @param projectRoot - Project root directory
|
|
45
|
+
* @returns Discovery result with modules, page dirs, and layout dirs
|
|
46
|
+
*/
|
|
47
|
+
export declare function discoverModules(modulesConfig: ResolvedModulesConfig, projectRoot: string): Promise<ModuleDiscoveryResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Get all page directories including both traditional and modular
|
|
50
|
+
*
|
|
51
|
+
* @param pagesDir - Traditional pages directory
|
|
52
|
+
* @param modulesConfig - Modules configuration (if any)
|
|
53
|
+
* @param projectRoot - Project root
|
|
54
|
+
* @returns Array of page directories with their route prefixes
|
|
55
|
+
*/
|
|
56
|
+
export declare function getAllPageDirs(pagesDir: string, modulesConfig: ResolvedModulesConfig | null, projectRoot: string): Promise<Array<{
|
|
57
|
+
dir: string;
|
|
58
|
+
prefix: string;
|
|
59
|
+
}>>;
|
|
60
|
+
/**
|
|
61
|
+
* Get all layout directories including both traditional and modular
|
|
62
|
+
*/
|
|
63
|
+
export declare function getAllLayoutDirs(layoutsDir: string, modulesConfig: ResolvedModulesConfig | null, projectRoot: string): Promise<Array<{
|
|
64
|
+
dir: string;
|
|
65
|
+
prefix: string;
|
|
66
|
+
}>>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nitro Integration Module for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides coordination between Avalon's Vite plugin and Nitro:
|
|
5
|
+
* - API routes: Auto-discovered by Nitro from `api/` directory
|
|
6
|
+
* - Page routes: Virtual module for SSR page component discovery
|
|
7
|
+
* - Middleware: Auto-discovered by Nitro from `middleware/` directory
|
|
8
|
+
*/
|
|
9
|
+
import type { Plugin, ViteDevServer } from 'vite';
|
|
10
|
+
import type { ResolvedAvalonConfig } from './types.ts';
|
|
11
|
+
import { type AvalonNitroConfig, type NitroConfigOutput } from '../nitro/config.ts';
|
|
12
|
+
export declare const VIRTUAL_MODULE_IDS: {
|
|
13
|
+
readonly PAGE_ROUTES: "virtual:avalon/page-routes";
|
|
14
|
+
readonly ISLAND_MANIFEST: "virtual:avalon/island-manifest";
|
|
15
|
+
readonly RUNTIME_CONFIG: "virtual:avalon/runtime-config";
|
|
16
|
+
readonly CONFIG: "virtual:avalon/config";
|
|
17
|
+
};
|
|
18
|
+
export declare const RESOLVED_VIRTUAL_IDS: {
|
|
19
|
+
readonly PAGE_ROUTES: string;
|
|
20
|
+
readonly ISLAND_MANIFEST: string;
|
|
21
|
+
readonly RUNTIME_CONFIG: string;
|
|
22
|
+
readonly CONFIG: string;
|
|
23
|
+
};
|
|
24
|
+
export interface NitroIntegrationResult {
|
|
25
|
+
nitroOptions: NitroConfigOutput;
|
|
26
|
+
plugins: Plugin[];
|
|
27
|
+
}
|
|
28
|
+
export interface NitroCoordinationPluginOptions {
|
|
29
|
+
avalonConfig: ResolvedAvalonConfig;
|
|
30
|
+
nitroConfig: AvalonNitroConfig;
|
|
31
|
+
verbose?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates the Nitro integration for Avalon — configuration, virtual modules,
|
|
35
|
+
* build plugins, and SSR coordination.
|
|
36
|
+
*
|
|
37
|
+
* Uses the Nitro v3 Vite plugin from `nitro/vite` for server route discovery,
|
|
38
|
+
* SSR rendering pipeline, and Rolldown-optimized bundling.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createNitroIntegration(avalonConfig: ResolvedAvalonConfig, nitroConfig?: AvalonNitroConfig): NitroIntegrationResult;
|
|
41
|
+
/**
|
|
42
|
+
* Coordination plugin: stores config/server refs, sets up SSR middleware and HMR,
|
|
43
|
+
* and prewarms core infrastructure modules (fire-and-forget).
|
|
44
|
+
*/
|
|
45
|
+
export declare function createNitroCoordinationPlugin(options: NitroCoordinationPluginOptions): Plugin;
|
|
46
|
+
/**
|
|
47
|
+
* Virtual modules plugin — page routes, island manifest, runtime config.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createVirtualModulesPlugin(options: NitroCoordinationPluginOptions): Plugin;
|
|
50
|
+
export declare function generateConfigModule(avalonConfig: ResolvedAvalonConfig, nitroConfig: AvalonNitroConfig): string;
|
|
51
|
+
export declare function getViteDevServer(): ViteDevServer | undefined;
|
|
52
|
+
export declare function getAvalonConfig(): ResolvedAvalonConfig | undefined;
|
|
53
|
+
export declare function isDevelopmentMode(): boolean;
|
|
54
|
+
declare global {
|
|
55
|
+
var __avalonLayoutResolver: unknown;
|
|
56
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{nitro as e}from"nitro/vite";import{stat as t}from"node:fs/promises";import{existsSync as n}from"node:fs";import{createRequire as r}from"node:module";import{dirname as i,join as a}from"node:path";import{createNitroConfig as o}from"../nitro/config.js";import{createNitroBuildPlugin as s,createIslandManifestPlugin as c,createSourceMapPlugin as l,createSourceMapConfig as u}from"../nitro/index.js";import{discoverScopedMiddleware as d,executeScopedMiddleware as f,clearMiddlewareCache as p}from"../middleware/index.js";import{generateErrorPage as m,generateFallback404 as h}from"../render/error-pages.js";import{collectCssFromModuleGraph as g,injectSsrCss as _}from"../render/collect-css.js";import{getUniversalCSSForHead as v}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as y}from"../islands/universal-head-collector.js";function b(e){let t=a(i(r(import.meta.url).resolve(`@useavalon/avalon`)),e);if(e.endsWith(`.ts`)&&!n(t)){let e=t.replace(/\.ts$/,`.js`);if(n(e))return e}return t}function x(e,t){let o=a(i(r(a(process.cwd(),`package.json`)).resolve(`@useavalon/${e}`)),t);if(t.endsWith(`.ts`)&&!n(o)){let e=o.replace(/\.ts$/,`.js`);if(n(e))return e}return o}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0`+VIRTUAL_MODULE_IDS.PAGE_ROUTES,ISLAND_MANIFEST:`\0`+VIRTUAL_MODULE_IDS.ISLAND_MANIFEST,RUNTIME_CONFIG:`\0`+VIRTUAL_MODULE_IDS.RUNTIME_CONFIG,CONFIG:`\0`+VIRTUAL_MODULE_IDS.CONFIG};export function createNitroIntegration(t,n={}){let r=o(n,t),i={preset:r.preset,serverDir:n.serverDir??r.serverDir??`./server`,routeRules:r.routeRules,runtimeConfig:r.runtimeConfig,renderer:n.renderer===!1?!1:r.renderer,compatibilityDate:r.compatibilityDate,scanDirs:[`.`]};r.publicRuntimeConfig&&(i.publicRuntimeConfig=r.publicRuntimeConfig),r.publicAssets&&(i.publicAssets=r.publicAssets),r.compressPublicAssets&&(i.compressPublicAssets=r.compressPublicAssets),r.serverEntry&&(i.serverEntry=r.serverEntry);let a=e(i),d=createNitroCoordinationPlugin({avalonConfig:t,nitroConfig:n,verbose:t.verbose}),f=createVirtualModulesPlugin({avalonConfig:t,nitroConfig:n,verbose:t.verbose}),p=s(t,n),m=c(t,{verbose:t.verbose,generatePreloadHints:!0}),h=l(u(n.preset??`node_server`,t.isDev));return{nitroOptions:r,plugins:[...Array.isArray(a)?a:[a],d,f,p,m,h]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,configResolved(e){globalThis.__avalonConfig=t},configureServer(e){globalThis.__viteDevServer=e;let r=null;async function i(){return r||=await d({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),r}function a(){r=null}A(e,t,n,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)}),O(e,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(r,a,o)=>{let s=r.url||`/`;if(s.endsWith(`.html`)&&(s=s.slice(0,-5)||`/`),s===`/index`&&(s=`/`),s.startsWith(`/@`)||s.startsWith(`/__`)||s.startsWith(`/node_modules/`)||s.startsWith(`/src/client/`)||s.startsWith(`/packages/`)||s.includes(`.`)&&!s.endsWith(`/`)||s.startsWith(`/api/`))return o();try{if(await E(e,s,r,a,i,n)||await L(e,s,t,a))return;let o=await R(e,s,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await D(e,s,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(m(e))}})},buildStart(){}}}async function E(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await f({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function D(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(h(t))}}async function O(e,t){let
|
|
1
|
+
import{nitro as e}from"nitro/vite";import{stat as t}from"node:fs/promises";import{existsSync as n}from"node:fs";import{createRequire as r}from"node:module";import{dirname as i,join as a}from"node:path";import{createNitroConfig as o}from"../nitro/config.js";import{createNitroBuildPlugin as s,createIslandManifestPlugin as c,createSourceMapPlugin as l,createSourceMapConfig as u}from"../nitro/index.js";import{discoverScopedMiddleware as d,executeScopedMiddleware as f,clearMiddlewareCache as p}from"../middleware/index.js";import{generateErrorPage as m,generateFallback404 as h}from"../render/error-pages.js";import{collectCssFromModuleGraph as g,injectSsrCss as _}from"../render/collect-css.js";import{getUniversalCSSForHead as v}from"../islands/universal-css-collector.js";import{getUniversalHeadForInjection as y}from"../islands/universal-head-collector.js";function b(e){let t=a(i(r(import.meta.url).resolve(`@useavalon/avalon`)),e);if(e.endsWith(`.ts`)&&!n(t)){let e=t.replace(/\.ts$/,`.js`);if(n(e))return e}return t}function x(e,t){let o=a(i(r(a(process.cwd(),`package.json`)).resolve(`@useavalon/${e}`)),t);if(t.endsWith(`.ts`)&&!n(o)){let e=o.replace(/\.ts$/,`.js`);if(n(e))return e}return o}export const VIRTUAL_MODULE_IDS={PAGE_ROUTES:`virtual:avalon/page-routes`,ISLAND_MANIFEST:`virtual:avalon/island-manifest`,RUNTIME_CONFIG:`virtual:avalon/runtime-config`,CONFIG:`virtual:avalon/config`};export const RESOLVED_VIRTUAL_IDS={PAGE_ROUTES:`\0`+VIRTUAL_MODULE_IDS.PAGE_ROUTES,ISLAND_MANIFEST:`\0`+VIRTUAL_MODULE_IDS.ISLAND_MANIFEST,RUNTIME_CONFIG:`\0`+VIRTUAL_MODULE_IDS.RUNTIME_CONFIG,CONFIG:`\0`+VIRTUAL_MODULE_IDS.CONFIG};export function createNitroIntegration(t,n={}){let r=o(n,t),i={preset:r.preset,serverDir:n.serverDir??r.serverDir??`./server`,routeRules:r.routeRules,runtimeConfig:r.runtimeConfig,renderer:n.renderer===!1?!1:r.renderer,compatibilityDate:r.compatibilityDate,scanDirs:[`.`]};r.publicRuntimeConfig&&(i.publicRuntimeConfig=r.publicRuntimeConfig),r.publicAssets&&(i.publicAssets=r.publicAssets),r.compressPublicAssets&&(i.compressPublicAssets=r.compressPublicAssets),r.serverEntry&&(i.serverEntry=r.serverEntry);let a=e(i),d=createNitroCoordinationPlugin({avalonConfig:t,nitroConfig:n,verbose:t.verbose}),f=createVirtualModulesPlugin({avalonConfig:t,nitroConfig:n,verbose:t.verbose}),p=s(t,n),m=c(t,{verbose:t.verbose,generatePreloadHints:!0}),h=l(u(n.preset??`node_server`,t.isDev));return{nitroOptions:r,plugins:[...Array.isArray(a)?a:[a],d,f,p,m,h]}}export function createNitroCoordinationPlugin(e){let{avalonConfig:t,verbose:n}=e;return{name:`avalon:nitro-coordination`,enforce:`pre`,configResolved(e){globalThis.__avalonConfig=t},configureServer(e){globalThis.__viteDevServer=e;let r=null;async function i(){return r||=await d({baseDir:`${e.config.root||process.cwd()}/src`,devMode:!1}),r}function a(){r=null}A(e,t,n,a),i().catch(e=>{console.warn(`[middleware] Failed to discover middleware:`,e)}),O(e,t.integrations,n).catch(e=>{console.error(`[prewarm] Core modules pre-warm failed:`,e)}),e.middlewares.use(async(r,a,o)=>{let s=r.url||`/`;if(s.endsWith(`.html`)&&(s=s.slice(0,-5)||`/`),s===`/index`&&(s=`/`),s.startsWith(`/@`)||s.startsWith(`/__`)||s.startsWith(`/node_modules/`)||s.startsWith(`/src/client/`)||s.startsWith(`/packages/`)||s.includes(`.`)&&!s.endsWith(`/`)||s.startsWith(`/api/`))return o();try{if(await E(e,s,r,a,i,n)||await L(e,s,t,a))return;let o=await R(e,s,t);if(o){a.statusCode=200,a.setHeader(`Content-Type`,`text/html`),a.end(o);return}await D(e,s,a,t)}catch(e){console.error(`[SSR Error]`,e),a.statusCode=500,a.setHeader(`Content-Type`,`text/html`),a.end(m(e))}})},buildStart(){}}}async function E(e,t,n,r,i,a){let o=performance.now(),s=await i();if(s.length===0)return!1;let c={};for(let[e,t]of Object.entries(n.headers))typeof t==`string`?c[e]=t:Array.isArray(t)&&(c[e]=t.join(`, `));let l=`http://${n.headers.host||`localhost`}${t}`,u=await f({url:l,method:n.method||`GET`,path:t,node:{req:n,res:r},req:new Request(l,{method:n.method||`GET`,headers:c}),context:{}},s,{devMode:!1}),d=performance.now()-o;return d>100&&console.warn(`⚠️ Slow middleware: ${d.toFixed(0)}ms for ${t}`),u?(r.statusCode=u.status,u.headers.forEach((e,t)=>{r.setHeader(t,e)}),r.end(await u.text()),!0):!1}async function D(e,t,n,r){try{let{discoverErrorPages:i,getErrorPageModule:a,generateDefaultErrorPage:o}=await import(`../nitro/error-handler.js`),s=a(404,await i({isDev:r.isDev,pagesDir:r.pagesDir,loadPageModule:async t=>await e.ssrLoadModule(t)}));if(s?.default&&typeof s.default==`function`){let{renderToHtml:e}=await import(`../render/ssr.js`),r=s.default,i=await e({component:()=>r({statusCode:404,message:`Page not found: ${t}`,url:t})},{});n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(i);return}let c=o(404,`Page not found: ${t}`,r.isDev);n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(c)}catch{n.statusCode=404,n.setHeader(`Content-Type`,`text/html`),n.end(h(t))}}async function O(e,t,n){let r=performance.now(),i=[{path:b(`src/render/ssr.ts`),assignTo:`ssr`},{path:b(`src/core/layout/enhanced-layout-resolver.ts`),assignTo:`layout`},{path:b(`src/middleware/index.ts`),assignTo:null},...t.map(e=>({path:x(e,`server/renderer.ts`),assignTo:null}))],a=(await Promise.allSettled(i.map(async({path:t,assignTo:n})=>{let r=await e.ssrLoadModule(t);n===`ssr`&&(F=r),n===`layout`&&(I=r)}))).filter(e=>e.status===`fulfilled`).length,o=performance.now()-r;n&&a>0&&console.log(`🔥 SSR ready in ${o.toFixed(0)}ms (${a}/${i.length} core modules)`)}export function createVirtualModulesPlugin(e){let{avalonConfig:t,nitroConfig:n,verbose:r}=e;return{name:`avalon:nitro-virtual-modules`,enforce:`pre`,resolveId(e){return e===VIRTUAL_MODULE_IDS.PAGE_ROUTES?RESOLVED_VIRTUAL_IDS.PAGE_ROUTES:e===VIRTUAL_MODULE_IDS.ISLAND_MANIFEST?RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST:e===VIRTUAL_MODULE_IDS.RUNTIME_CONFIG?RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG:e===VIRTUAL_MODULE_IDS.CONFIG?RESOLVED_VIRTUAL_IDS.CONFIG:null},async load(e){return e===RESOLVED_VIRTUAL_IDS.PAGE_ROUTES?await j(t,r):e===RESOLVED_VIRTUAL_IDS.ISLAND_MANIFEST?M():e===RESOLVED_VIRTUAL_IDS.RUNTIME_CONFIG?N(t,n):e===RESOLVED_VIRTUAL_IDS.CONFIG?generateConfigModule(t,n):null},handleHotUpdate({file:e,server:n}){if(e.includes(t.pagesDir)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.PAGE_ROUTES);e&&n.moduleGraph.invalidateModule(e)}if(e.includes(`vite.config`)||e.includes(`avalon.config`)||e.includes(`nitro.config`)){let e=n.moduleGraph.getModuleById(RESOLVED_VIRTUAL_IDS.CONFIG);e&&n.moduleGraph.invalidateModule(e)}}}}function A(e,t,n,r){e.watcher.on(`change`,e=>{e.includes(`_middleware`)&&(p(),r?.()),(e.includes(`/render/`)||e.includes(`/layout/`)||e.includes(`/islands/`))&&(F=null,I=null),(e.includes(`/layouts/`)||e.includes(`_layout`))&&globalThis.__avalonLayoutResolver?.clearCache?.()}),e.watcher.on(`add`,e=>{e.includes(`_middleware`)&&(p(),r?.())}),e.watcher.on(`unlink`,e=>{e.includes(`_middleware`)&&(p(),r?.())})}async function j(e,t){try{let{getAllPageDirs:t}=await import(`./module-discovery.js`),{discoverPageRoutesFromMultipleDirs:n}=await import(`../nitro/route-discovery.js`),r=await n(await t(e.pagesDir,e.modules,process.cwd()),{developmentMode:e.isDev});return`export const pageRoutes = ${JSON.stringify(r,null,2)};\nexport default pageRoutes;\n`}catch{return`export const pageRoutes = [];
|
|
2
2
|
export default pageRoutes;
|
|
3
3
|
`}}function M(){return`export const islandManifest = { islands: {}, clientEntry: "", css: [] };
|
|
4
4
|
export default islandManifest;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module provides the main `avalon()` function that creates a unified Vite plugin
|
|
5
|
+
* for the Avalon framework. It handles configuration resolution, integration activation,
|
|
6
|
+
* Nitro server integration, and wires up all the necessary Vite hooks.
|
|
7
|
+
*
|
|
8
|
+
* ISLAND DETECTION:
|
|
9
|
+
* Islands are detected by usage - any component used with an `island` prop in pages
|
|
10
|
+
* or layouts is automatically treated as an island. No fixed islands directory required.
|
|
11
|
+
*/
|
|
12
|
+
import type { Plugin, PluginOption, ViteDevServer } from 'vite';
|
|
13
|
+
import type { AvalonPluginConfig, IntegrationName, ResolvedAvalonConfig } from './types.ts';
|
|
14
|
+
import type { NitroConfigOutput } from '../nitro/config.ts';
|
|
15
|
+
declare global {
|
|
16
|
+
var __avalonConfig: ResolvedAvalonConfig | undefined;
|
|
17
|
+
var __viteDevServer: ViteDevServer | undefined;
|
|
18
|
+
var __nitroConfig: NitroConfigOutput | undefined;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Collects Vite plugins from all activated integrations.
|
|
22
|
+
*
|
|
23
|
+
* This function iterates through the activated integrations and calls their
|
|
24
|
+
* vitePlugin() method if implemented. The returned plugins are collected and
|
|
25
|
+
* flattened into a single array.
|
|
26
|
+
*
|
|
27
|
+
* Plugin ordering is handled to ensure correct application:
|
|
28
|
+
* - Lit plugins come first (DOM shim requirement)
|
|
29
|
+
* - Other framework plugins follow
|
|
30
|
+
*
|
|
31
|
+
* @param activeIntegrations - Set of activated integration names
|
|
32
|
+
* @param verbose - Whether to log detailed information
|
|
33
|
+
* @returns Promise resolving to an array of Vite plugins from integrations
|
|
34
|
+
*/
|
|
35
|
+
export declare function collectIntegrationPlugins(activeIntegrations: Set<IntegrationName>, verbose?: boolean): Promise<Plugin[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Creates the Avalon Vite plugin array
|
|
38
|
+
*
|
|
39
|
+
* @param config - Avalon configuration options
|
|
40
|
+
* @returns A promise that resolves to an array of Vite plugins that handle all Avalon functionality.
|
|
41
|
+
* Returns PluginOption[] to avoid TypeScript's excessive stack depth issues
|
|
42
|
+
* when comparing Plugin<any> arrays in Vite 8's complex type system.
|
|
43
|
+
*/
|
|
44
|
+
export declare function avalon(config?: AvalonPluginConfig): Promise<PluginOption[]>;
|
|
45
|
+
export declare function getResolvedConfig(): ResolvedAvalonConfig | undefined;
|
|
46
|
+
export declare function getPagesDir(): string;
|
|
47
|
+
export declare function getLayoutsDir(): string;
|
|
48
|
+
export declare function getNitroConfig(): NitroConfigOutput | undefined;
|
|
49
|
+
export declare function isNitroEnabled(): boolean;
|
|
50
|
+
export type { AvalonPluginConfig, IntegrationName, ResolvedAvalonConfig, ImageConfig, ResolvedImageConfig, } from './types.ts';
|
|
51
|
+
export type { AvalonNitroConfig, NitroConfigOutput } from '../nitro/config.ts';
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite Plugin Types for Avalon
|
|
3
|
+
*
|
|
4
|
+
* CONFIG PATH: Vite plugin runtime
|
|
5
|
+
* These types define the inline configuration passed to `avalon()` in
|
|
6
|
+
* `vite.config.ts`. The `resolveConfig()` function in `vite-plugin/config.ts`
|
|
7
|
+
* merges user options against `DEFAULT_CONFIG` to produce a `ResolvedAvalonConfig`.
|
|
8
|
+
*
|
|
9
|
+
* This path uses `IntegrationName[]` (simple string array) for integrations.
|
|
10
|
+
*
|
|
11
|
+
* There is a separate CLI config path (`schemas/integration-config.ts` →
|
|
12
|
+
* `config-loader.ts` → `startup.ts` → `cli.ts`) that reads `avalon.config.ts`
|
|
13
|
+
* from disk and uses `IntegrationConfigEntry[]` (objects with name/enabled/options).
|
|
14
|
+
* That path is NOT used during Vite plugin startup.
|
|
15
|
+
*/
|
|
16
|
+
import type { AvalonNitroConfig } from "../nitro/config.ts";
|
|
17
|
+
/**
|
|
18
|
+
* Image optimization configuration
|
|
19
|
+
*/
|
|
20
|
+
export interface ImageConfig {
|
|
21
|
+
/**
|
|
22
|
+
* Enable image optimization via vite-imagetools
|
|
23
|
+
* @default true
|
|
24
|
+
*/
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Default image format for optimized images
|
|
28
|
+
* @default "webp"
|
|
29
|
+
*/
|
|
30
|
+
defaultFormat?: "webp" | "avif" | "jpg" | "png";
|
|
31
|
+
/**
|
|
32
|
+
* Default image quality (1-100)
|
|
33
|
+
* @default 80
|
|
34
|
+
*/
|
|
35
|
+
quality?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Breakpoint widths for srcset generation
|
|
38
|
+
* @default [200, 400, 600, 800, 1200]
|
|
39
|
+
*/
|
|
40
|
+
widths?: number[];
|
|
41
|
+
/**
|
|
42
|
+
* Whether to strip EXIF and other metadata from images
|
|
43
|
+
* @default true
|
|
44
|
+
*/
|
|
45
|
+
removeMetadata?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* File patterns to include for image processing
|
|
48
|
+
* @default /^[^?]+\.(heif|avif|jpeg|jpg|png|tiff|webp|gif)(\?.*)?$/
|
|
49
|
+
*/
|
|
50
|
+
include?: string | RegExp | (string | RegExp)[];
|
|
51
|
+
/**
|
|
52
|
+
* File patterns to exclude from image processing
|
|
53
|
+
* @default "public/**\/*"
|
|
54
|
+
*/
|
|
55
|
+
exclude?: string | RegExp | (string | RegExp)[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolved image optimization configuration
|
|
59
|
+
*/
|
|
60
|
+
export interface ResolvedImageConfig {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
defaultFormat: "webp" | "avif" | "jpg" | "png";
|
|
63
|
+
quality: number;
|
|
64
|
+
widths: number[];
|
|
65
|
+
removeMetadata: boolean;
|
|
66
|
+
include: string | RegExp | (string | RegExp)[];
|
|
67
|
+
exclude: string | RegExp | (string | RegExp)[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Supported integration names
|
|
71
|
+
* These correspond to the @useavalon/* packages
|
|
72
|
+
*/
|
|
73
|
+
export type IntegrationName = "react" | "preact" | "vue" | "svelte" | "solid" | "lit" | "qwik";
|
|
74
|
+
/**
|
|
75
|
+
* MDX configuration options
|
|
76
|
+
*/
|
|
77
|
+
export interface MDXConfig {
|
|
78
|
+
/**
|
|
79
|
+
* JSX import source for MDX files
|
|
80
|
+
* @default "preact"
|
|
81
|
+
*/
|
|
82
|
+
jsxImportSource?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Enable syntax highlighting for code blocks
|
|
85
|
+
* @default true
|
|
86
|
+
*/
|
|
87
|
+
syntaxHighlighting?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Custom remark plugins
|
|
90
|
+
*/
|
|
91
|
+
remarkPlugins?: unknown[];
|
|
92
|
+
/**
|
|
93
|
+
* Custom rehype plugins
|
|
94
|
+
*/
|
|
95
|
+
rehypePlugins?: unknown[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Modular architecture configuration
|
|
99
|
+
* Enables co-located pages/layouts within feature modules
|
|
100
|
+
*/
|
|
101
|
+
export interface ModulesConfig {
|
|
102
|
+
/**
|
|
103
|
+
* Directory containing feature modules
|
|
104
|
+
* @example "app/modules"
|
|
105
|
+
*/
|
|
106
|
+
dir: string;
|
|
107
|
+
/**
|
|
108
|
+
* Name of the pages directory within each module
|
|
109
|
+
* @default "pages"
|
|
110
|
+
*/
|
|
111
|
+
pagesDirName?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Name of the layouts directory within each module
|
|
114
|
+
* @default "layouts"
|
|
115
|
+
*/
|
|
116
|
+
layoutsDirName?: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Configuration options for the Avalon Vite plugin
|
|
120
|
+
*/
|
|
121
|
+
export interface AvalonPluginConfig {
|
|
122
|
+
/**
|
|
123
|
+
* Directory containing page components for file-system routing
|
|
124
|
+
* @default "src/pages"
|
|
125
|
+
*/
|
|
126
|
+
pagesDir?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Directory containing layout components
|
|
129
|
+
* @default "src/layouts"
|
|
130
|
+
*/
|
|
131
|
+
layoutsDir?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Modular architecture configuration
|
|
134
|
+
* When set, discovers pages and layouts within feature modules
|
|
135
|
+
* Can be a string (just the dir) or full config object
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* // Simple - uses default 'pages' and 'layouts' folder names
|
|
140
|
+
* modules: 'app/modules'
|
|
141
|
+
*
|
|
142
|
+
* // Full config - customize folder names
|
|
143
|
+
* modules: {
|
|
144
|
+
* dir: 'app/modules',
|
|
145
|
+
* pagesDirName: 'views',
|
|
146
|
+
* layoutsDirName: 'layouts',
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
modules?: string | ModulesConfig;
|
|
151
|
+
/**
|
|
152
|
+
* Framework integrations to activate
|
|
153
|
+
* Simply list the framework names - the integration packages handle the rest
|
|
154
|
+
* @example ["react", "svelte", "lit"]
|
|
155
|
+
*/
|
|
156
|
+
integrations?: IntegrationName[];
|
|
157
|
+
/**
|
|
158
|
+
* MDX processing configuration
|
|
159
|
+
*/
|
|
160
|
+
mdx?: MDXConfig;
|
|
161
|
+
/**
|
|
162
|
+
* Image optimization configuration
|
|
163
|
+
* When enabled, Avalon auto-injects vite-imagetools with sensible defaults.
|
|
164
|
+
* Set to `false` to disable, or pass an object to customize.
|
|
165
|
+
*
|
|
166
|
+
* @default { enabled: true }
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* // Use defaults (webp, quality 80, standard breakpoints)
|
|
171
|
+
* image: true
|
|
172
|
+
*
|
|
173
|
+
* // Customize
|
|
174
|
+
* image: {
|
|
175
|
+
* defaultFormat: 'avif',
|
|
176
|
+
* quality: 90,
|
|
177
|
+
* widths: [320, 640, 1024, 1920],
|
|
178
|
+
* }
|
|
179
|
+
*
|
|
180
|
+
* // Disable
|
|
181
|
+
* image: false
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
image?: boolean | ImageConfig;
|
|
185
|
+
/**
|
|
186
|
+
* Nitro server runtime configuration
|
|
187
|
+
* When provided, enables Nitro integration for universal deployment
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```ts
|
|
191
|
+
* nitro: {
|
|
192
|
+
* preset: 'vercel',
|
|
193
|
+
* streaming: true,
|
|
194
|
+
* routeRules: {
|
|
195
|
+
* '/api/**': { cors: true },
|
|
196
|
+
* '/static/**': { cache: { maxAge: 86400 } },
|
|
197
|
+
* },
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
nitro?: AvalonNitroConfig;
|
|
202
|
+
/**
|
|
203
|
+
* Enable verbose logging during development
|
|
204
|
+
* @default false
|
|
205
|
+
*/
|
|
206
|
+
verbose?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Auto-discover integrations based on component file extensions
|
|
209
|
+
* When true, Avalon will automatically activate integrations
|
|
210
|
+
* based on the components you use, even if not listed in integrations
|
|
211
|
+
* @default true
|
|
212
|
+
*/
|
|
213
|
+
autoDiscoverIntegrations?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Validate integrations on startup
|
|
216
|
+
* When true, Avalon will check that all integrations
|
|
217
|
+
* implement the required interface correctly
|
|
218
|
+
* @default true
|
|
219
|
+
*/
|
|
220
|
+
validateIntegrations?: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Show warnings for integration issues
|
|
223
|
+
* When true, Avalon will log warnings for non-critical
|
|
224
|
+
* integration problems
|
|
225
|
+
* @default true
|
|
226
|
+
*/
|
|
227
|
+
showWarnings?: boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Enable lazy loading of integration Vite plugins
|
|
230
|
+
* When true (default), Avalon will only load Vite plugins for integrations
|
|
231
|
+
* that are actually used in your project, significantly improving cold start time.
|
|
232
|
+
*
|
|
233
|
+
* The lazy loading works by:
|
|
234
|
+
* 1. Scanning the islands directory to discover which frameworks are used
|
|
235
|
+
* 2. Only loading Vite plugins for those frameworks at startup
|
|
236
|
+
* 3. Loading additional plugins on-demand if new frameworks are encountered
|
|
237
|
+
*
|
|
238
|
+
* Set to false to load all configured integrations at startup (slower but predictable).
|
|
239
|
+
* @default true
|
|
240
|
+
*/
|
|
241
|
+
lazyIntegrations?: boolean;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Fully resolved MDX configuration with defaults applied
|
|
245
|
+
*/
|
|
246
|
+
export interface ResolvedMDXConfig {
|
|
247
|
+
jsxImportSource: string;
|
|
248
|
+
syntaxHighlighting: boolean;
|
|
249
|
+
remarkPlugins: unknown[];
|
|
250
|
+
rehypePlugins: unknown[];
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Resolved modular architecture configuration
|
|
254
|
+
*/
|
|
255
|
+
export interface ResolvedModulesConfig {
|
|
256
|
+
dir: string;
|
|
257
|
+
pagesDirName: string;
|
|
258
|
+
layoutsDirName: string;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Fully resolved configuration with defaults applied
|
|
262
|
+
*/
|
|
263
|
+
export interface ResolvedAvalonConfig {
|
|
264
|
+
pagesDir: string;
|
|
265
|
+
layoutsDir: string;
|
|
266
|
+
modules: ResolvedModulesConfig | null;
|
|
267
|
+
integrations: IntegrationName[];
|
|
268
|
+
mdx: ResolvedMDXConfig;
|
|
269
|
+
image: ResolvedImageConfig;
|
|
270
|
+
verbose: boolean;
|
|
271
|
+
autoDiscoverIntegrations: boolean;
|
|
272
|
+
validateIntegrations: boolean;
|
|
273
|
+
showWarnings: boolean;
|
|
274
|
+
lazyIntegrations: boolean;
|
|
275
|
+
isDev: boolean;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Re-export Nitro configuration types for convenience
|
|
279
|
+
*/
|
|
280
|
+
export type { AvalonNitroConfig } from "../nitro/config.ts";
|
|
281
|
+
export type { CacheOptions, RouteRule, NitroConfigOutput, AvalonRuntimeConfig, StaticAssetsConfig, } from "../nitro/config.ts";
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration Validation for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module provides validation functions to ensure that framework integrations
|
|
5
|
+
* implement the required interface correctly. Validation can be enabled via the
|
|
6
|
+
* `validateIntegrations` configuration option.
|
|
7
|
+
*/
|
|
8
|
+
import type { IntegrationName } from "./types.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Result of validating a single integration
|
|
11
|
+
*/
|
|
12
|
+
export interface ValidationResult {
|
|
13
|
+
/** The integration name that was validated */
|
|
14
|
+
integration: IntegrationName;
|
|
15
|
+
/** Whether the integration passed all required checks */
|
|
16
|
+
valid: boolean;
|
|
17
|
+
/** Critical errors that prevent the integration from working */
|
|
18
|
+
errors: string[];
|
|
19
|
+
/** Non-critical warnings about the integration */
|
|
20
|
+
warnings: string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of validating all active integrations
|
|
24
|
+
*/
|
|
25
|
+
export interface ValidationSummary {
|
|
26
|
+
/** Whether all integrations passed validation */
|
|
27
|
+
allValid: boolean;
|
|
28
|
+
/** Individual validation results for each integration */
|
|
29
|
+
results: ValidationResult[];
|
|
30
|
+
/** Total number of errors across all integrations */
|
|
31
|
+
totalErrors: number;
|
|
32
|
+
/** Total number of warnings across all integrations */
|
|
33
|
+
totalWarnings: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validate that an integration implements the required interface
|
|
37
|
+
*
|
|
38
|
+
* Checks for the following required properties:
|
|
39
|
+
* - name: string - Unique name of the integration
|
|
40
|
+
* - version: string - Version of the integration package
|
|
41
|
+
* - render: function - Server-side rendering function
|
|
42
|
+
* - getHydrationScript: function - Returns hydration script for client
|
|
43
|
+
* - config: function - Returns integration configuration
|
|
44
|
+
*
|
|
45
|
+
* Also checks optional properties if present:
|
|
46
|
+
* - vitePlugin: function (if provided)
|
|
47
|
+
*
|
|
48
|
+
* @param integration - The integration object to validate
|
|
49
|
+
* @returns ValidationResult with errors and warnings
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const result = validateIntegration(myIntegration);
|
|
54
|
+
* if (!result.valid) {
|
|
55
|
+
* console.error('Integration validation failed:', result.errors);
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function validateIntegration(integration: unknown): ValidationResult;
|
|
60
|
+
/**
|
|
61
|
+
* Validate all active integrations in the registry
|
|
62
|
+
*
|
|
63
|
+
* Iterates through all integrations that have been activated and validates
|
|
64
|
+
* each one against the required interface.
|
|
65
|
+
*
|
|
66
|
+
* @param activeIntegrations - Set of integration names that have been activated
|
|
67
|
+
* @param showWarnings - Whether to include warnings in the results
|
|
68
|
+
* @returns ValidationSummary with results for all integrations
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const activeIntegrations = new Set<IntegrationName>(['react', 'vue']);
|
|
73
|
+
* const summary = validateActiveIntegrations(activeIntegrations, true);
|
|
74
|
+
* if (!summary.allValid) {
|
|
75
|
+
* console.error(`${summary.totalErrors} validation errors found`);
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function validateActiveIntegrations(activeIntegrations: Set<IntegrationName>, showWarnings?: boolean): ValidationSummary;
|
|
80
|
+
/**
|
|
81
|
+
* Format validation results for console output
|
|
82
|
+
*
|
|
83
|
+
* @param summary - The validation summary to format
|
|
84
|
+
* @returns Formatted string for console output
|
|
85
|
+
*/
|
|
86
|
+
export declare function formatValidationResults(summary: ValidationSummary): string;
|
|
87
|
+
/**
|
|
88
|
+
* Validate a single integration by name from the registry
|
|
89
|
+
*
|
|
90
|
+
* @param name - The integration name to validate
|
|
91
|
+
* @returns ValidationResult or null if integration not found
|
|
92
|
+
*/
|
|
93
|
+
export declare function validateIntegrationByName(name: IntegrationName): ValidationResult | null;
|