@useavalon/avalon 0.1.23 → 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/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,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced TypeScript support for file-system routing
|
|
3
|
+
*
|
|
4
|
+
* This module provides strongly typed interfaces, utility types, and type guards
|
|
5
|
+
* for the file-system routing system, ensuring type safety throughout the routing pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import type { ComponentType } from 'preact';
|
|
8
|
+
import type { LoaderContext, Metadata } from '../schemas/routing.ts';
|
|
9
|
+
import type { LayoutConfig } from '../schemas/layout.ts';
|
|
10
|
+
/**
|
|
11
|
+
* Extract route parameters from a route pattern string
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* type BlogParams = ExtractRouteParams<'/blog/[slug]'>; // { slug: string }
|
|
16
|
+
* type UserParams = ExtractRouteParams<'/users/[id]/posts/[postId]'>; // { id: string; postId: string }
|
|
17
|
+
* type CatchAllParams = ExtractRouteParams<'/docs/[...path]'>; // { path: string[] }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export type ExtractRouteParams<T extends string> = T extends `${string}[${infer Param}]${infer Rest}` ? Param extends `...${infer RestParam}` ? {
|
|
21
|
+
[K in RestParam]: string[];
|
|
22
|
+
} & ExtractRouteParams<Rest> : Param extends `${infer OptionalParam}?` ? {
|
|
23
|
+
[K in OptionalParam]?: string;
|
|
24
|
+
} & ExtractRouteParams<Rest> : {
|
|
25
|
+
[K in Param]: string;
|
|
26
|
+
} & ExtractRouteParams<Rest> : Record<PropertyKey, never>;
|
|
27
|
+
/**
|
|
28
|
+
* Extract optional route parameters from a route pattern string
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* type OptionalParams = ExtractOptionalParams<'/blog/[[...slug]]'>; // { slug?: string[] }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export type ExtractOptionalParams<T extends string> = T extends `${string}[[${infer Param}]]${infer Rest}` ? Param extends `...${infer RestParam}` ? {
|
|
36
|
+
[K in RestParam]?: string[];
|
|
37
|
+
} & ExtractOptionalParams<Rest> : {
|
|
38
|
+
[K in Param]?: string;
|
|
39
|
+
} & ExtractOptionalParams<Rest> : Record<PropertyKey, never>;
|
|
40
|
+
/**
|
|
41
|
+
* Combine required and optional route parameters
|
|
42
|
+
*/
|
|
43
|
+
export type RouteParameters<T extends string> = ExtractRouteParams<T> & ExtractOptionalParams<T>;
|
|
44
|
+
/**
|
|
45
|
+
* Strongly typed page component with route parameters
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const BlogPost: TypedPageComponent<'/blog/[slug]'> = ({ params, query, data }) => {
|
|
50
|
+
* // params.slug is typed as string
|
|
51
|
+
* return <div>Blog post: {params.slug}</div>;
|
|
52
|
+
* };
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export type TypedPageComponent<TRoute extends string = string> = ComponentType<{
|
|
56
|
+
params: RouteParameters<TRoute>;
|
|
57
|
+
query: URLSearchParams;
|
|
58
|
+
data?: unknown;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Page component with custom data type
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* interface BlogPostData {
|
|
66
|
+
* title: string;
|
|
67
|
+
* content: string;
|
|
68
|
+
* }
|
|
69
|
+
*
|
|
70
|
+
* const BlogPost: TypedPageComponentWithData<'/blog/[slug]', BlogPostData> = ({ params, data }) => {
|
|
71
|
+
* // data is typed as BlogPostData | undefined
|
|
72
|
+
* return <div>{data?.title}</div>;
|
|
73
|
+
* };
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export type TypedPageComponentWithData<TRoute extends string, TData> = ComponentType<{
|
|
77
|
+
params: RouteParameters<TRoute>;
|
|
78
|
+
query: URLSearchParams;
|
|
79
|
+
data?: TData;
|
|
80
|
+
}>;
|
|
81
|
+
/**
|
|
82
|
+
* Strongly typed metadata generator function
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const generateMetadata: TypedMetadataGenerator<'/blog/[slug]'> = async ({ slug }) => {
|
|
87
|
+
* // slug is typed as string
|
|
88
|
+
* return {
|
|
89
|
+
* title: `Blog Post: ${slug}`,
|
|
90
|
+
* description: `Read about ${slug}`,
|
|
91
|
+
* };
|
|
92
|
+
* };
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export type TypedMetadataGenerator<TRoute extends string> = (params: RouteParameters<TRoute>) => Promise<Metadata>;
|
|
96
|
+
/**
|
|
97
|
+
* Metadata generator with custom context
|
|
98
|
+
*/
|
|
99
|
+
export type TypedMetadataGeneratorWithContext<TRoute extends string, TContext = unknown> = (params: RouteParameters<TRoute>, context: TContext) => Promise<Metadata>;
|
|
100
|
+
/**
|
|
101
|
+
* Strongly typed page loader function
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const loader: TypedPageLoader<'/blog/[slug]', BlogPostData> = async ({ params, request }) => {
|
|
106
|
+
* // params.slug is typed as string
|
|
107
|
+
* const post = await fetchBlogPost(params.slug);
|
|
108
|
+
* return post;
|
|
109
|
+
* };
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export type TypedPageLoader<TRoute extends string, TData = unknown> = (context: LoaderContext & {
|
|
113
|
+
params: RouteParameters<TRoute>;
|
|
114
|
+
}) => Promise<TData>;
|
|
115
|
+
/**
|
|
116
|
+
* Page loader with custom context
|
|
117
|
+
*/
|
|
118
|
+
export type TypedPageLoaderWithContext<TRoute extends string, TData = unknown, TContext = unknown> = (context: LoaderContext & {
|
|
119
|
+
params: RouteParameters<TRoute>;
|
|
120
|
+
}, customContext: TContext) => Promise<TData>;
|
|
121
|
+
/**
|
|
122
|
+
* Strongly typed route page module
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const pageModule: TypedRoutePageModule<'/blog/[slug]', BlogPostData> = {
|
|
127
|
+
* default: BlogPostComponent,
|
|
128
|
+
* generateMetadata: async ({ slug }) => ({ title: slug }),
|
|
129
|
+
* loader: async ({ params }) => fetchBlogPost(params.slug),
|
|
130
|
+
* };
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export type TypedRoutePageModule<TRoute extends string, TData = unknown> = {
|
|
134
|
+
default: TypedPageComponent<TRoute>;
|
|
135
|
+
layoutConfig?: LayoutConfig;
|
|
136
|
+
generateMetadata?: TypedMetadataGenerator<TRoute>;
|
|
137
|
+
loader?: TypedPageLoader<TRoute, TData>;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Strongly typed API handler function
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* export const GET: TypedApiHandler<'/api/users/[id]'> = async (request, { params }) => {
|
|
145
|
+
* // params.id is typed as string
|
|
146
|
+
* const user = await getUser(params.id);
|
|
147
|
+
* return Response.json(user);
|
|
148
|
+
* };
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export type TypedApiHandler<TRoute extends string> = (request: Request, context: LoaderContext & {
|
|
152
|
+
params: RouteParameters<TRoute>;
|
|
153
|
+
}) => Promise<Response>;
|
|
154
|
+
/**
|
|
155
|
+
* Strongly typed API module with all HTTP methods
|
|
156
|
+
*/
|
|
157
|
+
export type TypedApiModule<TRoute extends string> = {
|
|
158
|
+
GET?: TypedApiHandler<TRoute>;
|
|
159
|
+
POST?: TypedApiHandler<TRoute>;
|
|
160
|
+
PUT?: TypedApiHandler<TRoute>;
|
|
161
|
+
DELETE?: TypedApiHandler<TRoute>;
|
|
162
|
+
PATCH?: TypedApiHandler<TRoute>;
|
|
163
|
+
HEAD?: TypedApiHandler<TRoute>;
|
|
164
|
+
OPTIONS?: TypedApiHandler<TRoute>;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Route pattern validation
|
|
168
|
+
*/
|
|
169
|
+
export type ValidRoutePattern<T extends string> = T extends `${string}[${string}]${string}` ? T : T extends `${string}(${string})${string}` ? T : T extends `${string}_${string}` ? never : T;
|
|
170
|
+
/**
|
|
171
|
+
* Valid file extensions for routes
|
|
172
|
+
*/
|
|
173
|
+
export type ValidRouteExtension = '.tsx' | '.ts' | '.jsx' | '.js';
|
|
174
|
+
/**
|
|
175
|
+
* Route file path validation
|
|
176
|
+
*/
|
|
177
|
+
export type ValidRouteFile<T extends string> = T extends `${string}${ValidRouteExtension}` ? T extends `${string}_${string}` ? never : T : never;
|
|
178
|
+
/**
|
|
179
|
+
* Validate that a component accepts the correct props for a route
|
|
180
|
+
*/
|
|
181
|
+
export type ValidatePageComponent<TRoute extends string, TComponent> = TComponent extends ComponentType<infer TProps> ? TProps extends {
|
|
182
|
+
params: RouteParameters<TRoute>;
|
|
183
|
+
} ? TComponent : never : never;
|
|
184
|
+
/**
|
|
185
|
+
* Props validation for page components
|
|
186
|
+
*/
|
|
187
|
+
export interface PageComponentProps<TRoute extends string = string, TData = unknown> {
|
|
188
|
+
params: RouteParameters<TRoute>;
|
|
189
|
+
query: URLSearchParams;
|
|
190
|
+
data?: TData;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Validate page component props
|
|
194
|
+
*/
|
|
195
|
+
export type ValidatePageProps<TRoute extends string, TProps> = TProps extends PageComponentProps<TRoute> ? TProps : never;
|
|
196
|
+
/**
|
|
197
|
+
* Check if a route has dynamic segments
|
|
198
|
+
*/
|
|
199
|
+
export type HasDynamicSegments<T extends string> = T extends `${string}[${string}]${string}` ? true : false;
|
|
200
|
+
/**
|
|
201
|
+
* Check if a route has catch-all segments
|
|
202
|
+
*/
|
|
203
|
+
export type HasCatchAllSegments<T extends string> = T extends `${string}[...${string}]${string}` ? true : false;
|
|
204
|
+
/**
|
|
205
|
+
* Check if a route has optional segments
|
|
206
|
+
*/
|
|
207
|
+
export type HasOptionalSegments<T extends string> = T extends `${string}[[${string}]]${string}` ? true : false;
|
|
208
|
+
/**
|
|
209
|
+
* Get the static parts of a route
|
|
210
|
+
*/
|
|
211
|
+
export type GetStaticParts<T extends string> = T extends `${infer Static}[${string}]${infer Rest}` ? Static | GetStaticParts<Rest> : T;
|
|
212
|
+
/**
|
|
213
|
+
* Count dynamic segments in a route
|
|
214
|
+
*/
|
|
215
|
+
export type CountDynamicSegments<T extends string, Count extends readonly unknown[] = []> = T extends `${string}[${string}]${infer Rest}` ? CountDynamicSegments<Rest, [...Count, unknown]> : Count['length'];
|
|
216
|
+
/**
|
|
217
|
+
* Route error types
|
|
218
|
+
*/
|
|
219
|
+
export type RouteErrorType = 'ROUTE_NOT_FOUND' | 'INVALID_PARAMS' | 'LOADER_ERROR' | 'METADATA_ERROR' | 'COMPONENT_ERROR' | 'VALIDATION_ERROR';
|
|
220
|
+
/**
|
|
221
|
+
* Route error with context
|
|
222
|
+
*/
|
|
223
|
+
export interface RouteError<TRoute extends string = string> {
|
|
224
|
+
type: RouteErrorType;
|
|
225
|
+
route: TRoute;
|
|
226
|
+
params?: Partial<RouteParameters<TRoute>>;
|
|
227
|
+
message: string;
|
|
228
|
+
originalError?: Error;
|
|
229
|
+
suggestions?: string[];
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Error boundary props for routes
|
|
233
|
+
*/
|
|
234
|
+
export interface RouteErrorBoundaryProps<TRoute extends string = string> {
|
|
235
|
+
error: RouteError<TRoute>;
|
|
236
|
+
retry: () => void;
|
|
237
|
+
fallback?: ComponentType<{
|
|
238
|
+
error: RouteError<TRoute>;
|
|
239
|
+
}>;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Route debugging information
|
|
243
|
+
*/
|
|
244
|
+
export interface RouteDebugInfo<TRoute extends string = string> {
|
|
245
|
+
route: TRoute;
|
|
246
|
+
params: RouteParameters<TRoute>;
|
|
247
|
+
staticParts: string[];
|
|
248
|
+
dynamicSegments: string[];
|
|
249
|
+
hasOptionalSegments: HasOptionalSegments<TRoute>;
|
|
250
|
+
hasCatchAllSegments: HasCatchAllSegments<TRoute>;
|
|
251
|
+
priority: number;
|
|
252
|
+
filePath: string;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Route performance metrics
|
|
256
|
+
*/
|
|
257
|
+
export interface RoutePerformanceMetrics {
|
|
258
|
+
discoveryTime: number;
|
|
259
|
+
loadTime: number;
|
|
260
|
+
renderTime: number;
|
|
261
|
+
metadataResolutionTime: number;
|
|
262
|
+
cacheHits: number;
|
|
263
|
+
cacheMisses: number;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Type guard for route parameters
|
|
267
|
+
*/
|
|
268
|
+
export declare function isValidRouteParams<TRoute extends string>(params: unknown, expectedParams: (keyof RouteParameters<TRoute>)[]): params is RouteParameters<TRoute>;
|
|
269
|
+
/**
|
|
270
|
+
* Type guard for page component props
|
|
271
|
+
*/
|
|
272
|
+
export declare function isValidPageProps<TRoute extends string>(props: unknown, expectedParams: (keyof RouteParameters<TRoute>)[]): props is PageComponentProps<TRoute>;
|
|
273
|
+
/**
|
|
274
|
+
* Validate route pattern syntax
|
|
275
|
+
*/
|
|
276
|
+
export declare function isValidRoutePattern(pattern: string): boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Create a typed page component with parameter validation
|
|
279
|
+
*/
|
|
280
|
+
export declare function createTypedPageComponent<TRoute extends string>(component: TypedPageComponent<TRoute>, expectedParams: (keyof RouteParameters<TRoute>)[]): TypedPageComponent<TRoute>;
|
|
281
|
+
/**
|
|
282
|
+
* Create a typed metadata generator with parameter validation
|
|
283
|
+
*/
|
|
284
|
+
export declare function createTypedMetadataGenerator<TRoute extends string>(generator: TypedMetadataGenerator<TRoute>, expectedParams: (keyof RouteParameters<TRoute>)[]): TypedMetadataGenerator<TRoute>;
|
|
285
|
+
/**
|
|
286
|
+
* Create a typed page loader with parameter validation
|
|
287
|
+
*/
|
|
288
|
+
export declare function createTypedPageLoader<TRoute extends string, TData = unknown>(loader: TypedPageLoader<TRoute, TData>, expectedParams: (keyof RouteParameters<TRoute>)[]): TypedPageLoader<TRoute, TData>;
|
|
289
|
+
/**
|
|
290
|
+
* Validate component accepts correct props for a route
|
|
291
|
+
*/
|
|
292
|
+
export declare function validatePageComponent<TRoute extends string>(component: unknown, _expectedParams: (keyof RouteParameters<TRoute>)[]): component is TypedPageComponent<TRoute>;
|
|
293
|
+
/**
|
|
294
|
+
* Create a typed API handler with parameter validation
|
|
295
|
+
*/
|
|
296
|
+
export declare function createTypedApiHandler<TRoute extends string>(handler: TypedApiHandler<TRoute>, expectedParams: (keyof RouteParameters<TRoute>)[]): TypedApiHandler<TRoute>;
|
|
297
|
+
export type { RouteParams, LoaderContext, Metadata, PageProps, RoutePageModule, FileSystemRoute, ResolvedMetadata, } from '../schemas/routing.ts';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev-Only Logging Utilities
|
|
3
|
+
*
|
|
4
|
+
* These functions provide environment-aware logging that only outputs in development mode.
|
|
5
|
+
* In production (NODE_ENV=production), all logging is suppressed for better performance.
|
|
6
|
+
*
|
|
7
|
+
* @module dev-logger
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Check if we're in development mode
|
|
11
|
+
* Returns true if NODE_ENV is not set to "production"
|
|
12
|
+
*/
|
|
13
|
+
export declare function isDev(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Check if verbose logging is enabled
|
|
16
|
+
* Returns true only if AVALON_VERBOSE=1 is set
|
|
17
|
+
*/
|
|
18
|
+
export declare function isVerbose(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Log a message only in development mode AND when AVALON_VERBOSE=1 is set.
|
|
21
|
+
* By default this is a no-op — set AVALON_VERBOSE=1 to enable diagnostic output.
|
|
22
|
+
*
|
|
23
|
+
* @param args - Arguments to pass to console.log
|
|
24
|
+
*/
|
|
25
|
+
export declare function devLog(...args: unknown[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* Log a warning only in development mode
|
|
28
|
+
* In production, this is a no-op for performance
|
|
29
|
+
*
|
|
30
|
+
* @param args - Arguments to pass to console.warn
|
|
31
|
+
*/
|
|
32
|
+
export declare function devWarn(...args: unknown[]): void;
|
|
33
|
+
/**
|
|
34
|
+
* Log an error only in development mode
|
|
35
|
+
* In production, this is a no-op for performance
|
|
36
|
+
*
|
|
37
|
+
* @param args - Arguments to pass to console.error
|
|
38
|
+
*/
|
|
39
|
+
export declare function devError(...args: unknown[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Log render timing information for an island component
|
|
42
|
+
* Only logs in development mode AND when AVALON_VERBOSE=1 is set
|
|
43
|
+
* Warns when render time exceeds the threshold
|
|
44
|
+
*
|
|
45
|
+
* @param src - The island source path
|
|
46
|
+
* @param durationMs - The render duration in milliseconds
|
|
47
|
+
* @param threshold - Optional threshold for slow render warning (default: 100ms)
|
|
48
|
+
*/
|
|
49
|
+
export declare function logRenderTiming(src: string, durationMs: number, threshold?: number): void;
|
|
50
|
+
/**
|
|
51
|
+
* Log a cache hit event (dev mode only)
|
|
52
|
+
*
|
|
53
|
+
* @param cacheType - The type of cache (e.g., 'analysis', 'path', 'framework')
|
|
54
|
+
* @param key - The cache key that was hit
|
|
55
|
+
*/
|
|
56
|
+
export declare function logCacheHit(cacheType: string, key: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Log a cache miss event (dev mode only)
|
|
59
|
+
*
|
|
60
|
+
* @param cacheType - The type of cache (e.g., 'analysis', 'path', 'framework')
|
|
61
|
+
* @param key - The cache key that was missed
|
|
62
|
+
*/
|
|
63
|
+
export declare function logCacheMiss(cacheType: string, key: string): void;
|
|
64
|
+
export declare class DevLogger {
|
|
65
|
+
private readonly tasks;
|
|
66
|
+
private spinnerInterval?;
|
|
67
|
+
private currentFrame;
|
|
68
|
+
private readonly startTime;
|
|
69
|
+
private readonly originalConsoleLog;
|
|
70
|
+
private readonly originalConsoleWarn;
|
|
71
|
+
private readonly originalConsoleError;
|
|
72
|
+
private readonly suppressedLogs;
|
|
73
|
+
private readonly headerLines;
|
|
74
|
+
constructor();
|
|
75
|
+
private suppressConsole;
|
|
76
|
+
restoreConsole(): void;
|
|
77
|
+
addTask(id: string, name: string): void;
|
|
78
|
+
startTask(id: string): void;
|
|
79
|
+
completeTask(id: string): void;
|
|
80
|
+
private render;
|
|
81
|
+
startSpinner(): void;
|
|
82
|
+
stopSpinner(): void;
|
|
83
|
+
finish(serverUrl: string, viteUrl?: string, hmrUrl?: string): void;
|
|
84
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem utilities for Avalon.
|
|
3
|
+
* Provides Node.js-compatible implementations of common filesystem
|
|
4
|
+
* functions used throughout the codebase.
|
|
5
|
+
*/
|
|
6
|
+
export interface WalkEntry {
|
|
7
|
+
path: string;
|
|
8
|
+
name: string;
|
|
9
|
+
isFile: boolean;
|
|
10
|
+
isDirectory: boolean;
|
|
11
|
+
isSymlink: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface WalkOptions {
|
|
14
|
+
maxDepth?: number;
|
|
15
|
+
includeFiles?: boolean;
|
|
16
|
+
includeDirs?: boolean;
|
|
17
|
+
includeSymlinks?: boolean;
|
|
18
|
+
match?: RegExp[];
|
|
19
|
+
skip?: RegExp[];
|
|
20
|
+
exts?: string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Walks a directory tree yielding entries, compatible with @std/fs walk().
|
|
24
|
+
*/
|
|
25
|
+
export declare function walk(root: string, options?: WalkOptions): AsyncIterableIterator<WalkEntry>;
|
|
26
|
+
/**
|
|
27
|
+
* Ensures a directory exists, creating it recursively if needed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function ensureDir(dir: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Check if a file or directory exists.
|
|
32
|
+
*/
|
|
33
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Synchronous check if a file or directory exists.
|
|
36
|
+
*/
|
|
37
|
+
export declare function existsSync(path: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Empties a directory by removing all contents.
|
|
40
|
+
*/
|
|
41
|
+
export declare function emptyDir(dir: string): Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-Discovery for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module handles automatic discovery of framework integrations
|
|
5
|
+
* based on island prop usage in pages and layouts. It scans for components
|
|
6
|
+
* used with the `island` prop and detects their framework from file extensions
|
|
7
|
+
* and content.
|
|
8
|
+
*/
|
|
9
|
+
import type { IntegrationName } from "./types.ts";
|
|
10
|
+
/**
|
|
11
|
+
* Discover integrations from files in the islands directory
|
|
12
|
+
*
|
|
13
|
+
* Scans the specified directory for component files and determines
|
|
14
|
+
* which framework integrations are needed based on file extensions
|
|
15
|
+
* and naming conventions.
|
|
16
|
+
*
|
|
17
|
+
* @param islandsDir - Path to the islands directory (relative or absolute)
|
|
18
|
+
* @param projectRoot - Optional project root for resolving relative paths
|
|
19
|
+
* @returns Set of discovered integration names
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const integrations = await discoverIntegrationsFromFiles("src/islands");
|
|
24
|
+
* // Returns Set { "vue", "svelte", "preact" } based on files found
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function discoverIntegrationsFromFiles(islandsDir: string, projectRoot?: string): Promise<Set<IntegrationName>>;
|
|
28
|
+
/**
|
|
29
|
+
* Detect the integration name from a file name
|
|
30
|
+
*
|
|
31
|
+
* Uses file extensions and naming conventions to determine
|
|
32
|
+
* which framework integration a component file belongs to.
|
|
33
|
+
*
|
|
34
|
+
* @param fileName - The file name to analyze
|
|
35
|
+
* @returns The integration name or null if not a supported component file
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* detectIntegrationFromFileName("Counter.vue") // "vue"
|
|
40
|
+
* detectIntegrationFromFileName("Button.svelte") // "svelte"
|
|
41
|
+
* detectIntegrationFromFileName("Card.solid.tsx") // "solid"
|
|
42
|
+
* detectIntegrationFromFileName("Form.tsx") // "preact" (default)
|
|
43
|
+
* detectIntegrationFromFileName("styles.css") // null
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function detectIntegrationFromFileName(fileName: string): IntegrationName | null;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a file extension is supported for island components
|
|
49
|
+
*
|
|
50
|
+
* @param extension - The file extension (including the dot)
|
|
51
|
+
* @returns True if the extension is supported
|
|
52
|
+
*/
|
|
53
|
+
export declare function isSupportedExtension(extension: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get all supported file extensions
|
|
56
|
+
*
|
|
57
|
+
* @returns Array of supported file extensions
|
|
58
|
+
*/
|
|
59
|
+
export declare function getSupportedExtensions(): readonly string[];
|
|
60
|
+
/**
|
|
61
|
+
* Discover integrations by scanning pages and layouts for island prop usage.
|
|
62
|
+
*
|
|
63
|
+
* This function scans page and layout files for components used with the `island` prop,
|
|
64
|
+
* then resolves the import paths to detect which frameworks are needed.
|
|
65
|
+
*
|
|
66
|
+
* @param pagesDir - Path to the pages directory
|
|
67
|
+
* @param layoutsDir - Path to the layouts directory
|
|
68
|
+
* @param projectRoot - Optional project root for resolving relative paths
|
|
69
|
+
* @param modulesDir - Optional modules directory for modular architecture
|
|
70
|
+
* @returns Set of discovered integration names
|
|
71
|
+
*/
|
|
72
|
+
export declare function discoverIntegrationsFromIslandUsage(pagesDir: string, layoutsDir: string, projectRoot?: string, modulesDir?: string): Promise<Set<IntegrationName>>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Resolution for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module provides default configuration values and the resolution
|
|
5
|
+
* function that merges user configuration with defaults.
|
|
6
|
+
*/
|
|
7
|
+
import type { AvalonPluginConfig, ResolvedAvalonConfig, ResolvedMDXConfig, ResolvedImageConfig } from "./types.ts";
|
|
8
|
+
/**
|
|
9
|
+
* Default MDX configuration values
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_MDX_CONFIG: ResolvedMDXConfig;
|
|
12
|
+
/**
|
|
13
|
+
* Default image optimization configuration values
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_IMAGE_CONFIG: ResolvedImageConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Default configuration values for the Avalon plugin
|
|
18
|
+
* These are used when the user doesn't provide specific values
|
|
19
|
+
*/
|
|
20
|
+
export declare const DEFAULT_CONFIG: Omit<ResolvedAvalonConfig, "isDev">;
|
|
21
|
+
/**
|
|
22
|
+
* Default modules configuration values
|
|
23
|
+
*/
|
|
24
|
+
export declare const DEFAULT_MODULES_CONFIG: {
|
|
25
|
+
pagesDirName: string;
|
|
26
|
+
layoutsDirName: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Resolves user configuration by merging with defaults
|
|
30
|
+
*
|
|
31
|
+
* @param userConfig - Partial configuration provided by the user
|
|
32
|
+
* @param isDev - Whether the application is running in development mode
|
|
33
|
+
* @returns Fully resolved configuration with all defaults applied
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const resolved = resolveConfig({ integrations: ["react"] }, true);
|
|
38
|
+
* // resolved.pagesDir === "src/pages" (default)
|
|
39
|
+
* // resolved.integrations === ["react"] (user provided)
|
|
40
|
+
* // resolved.isDev === true
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveConfig(userConfig: AvalonPluginConfig | undefined, isDev: boolean): ResolvedAvalonConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Result of directory existence check
|
|
46
|
+
*/
|
|
47
|
+
export interface DirectoryCheckResult {
|
|
48
|
+
/** The directory path that was checked */
|
|
49
|
+
path: string;
|
|
50
|
+
/** The resolved absolute path */
|
|
51
|
+
absolutePath: string;
|
|
52
|
+
/** Whether the directory exists */
|
|
53
|
+
exists: boolean;
|
|
54
|
+
/** The type of directory (pages, layouts) */
|
|
55
|
+
type: "pages" | "layouts";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if configured directories exist and log warnings for missing ones
|
|
59
|
+
*
|
|
60
|
+
* This function checks if the configured directories (pagesDir, layoutsDir)
|
|
61
|
+
* exist on the filesystem. If a directory doesn't exist, it logs a warning but
|
|
62
|
+
* does NOT throw an error, allowing the application to continue.
|
|
63
|
+
*
|
|
64
|
+
* @param config - The resolved Avalon configuration
|
|
65
|
+
* @param projectRoot - The root directory of the project (defaults to process.cwd())
|
|
66
|
+
* @returns Array of directory check results
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const results = checkDirectoriesExist(resolvedConfig, '/path/to/project');
|
|
71
|
+
* // Logs warnings for any missing directories
|
|
72
|
+
* // Returns results for programmatic access
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function checkDirectoriesExist(config: ResolvedAvalonConfig, projectRoot?: string): DirectoryCheckResult[];
|
|
76
|
+
/**
|
|
77
|
+
* Log a summary of directory check results
|
|
78
|
+
*
|
|
79
|
+
* @param results - The directory check results
|
|
80
|
+
* @param verbose - Whether to log verbose output
|
|
81
|
+
*/
|
|
82
|
+
export declare function logDirectoryCheckSummary(results: DirectoryCheckResult[], verbose: boolean): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Classes for Avalon Vite Plugin
|
|
3
|
+
*
|
|
4
|
+
* This module provides custom error classes for configuration and integration errors.
|
|
5
|
+
* These errors include contextual information to help developers quickly identify
|
|
6
|
+
* and fix issues.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Thrown when configuration is invalid
|
|
10
|
+
*
|
|
11
|
+
* This error includes the specific field name and value that caused the error,
|
|
12
|
+
* making it easier to identify and fix configuration issues.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* throw new AvalonConfigError(
|
|
17
|
+
* "must be a valid directory path",
|
|
18
|
+
* "islandsDir",
|
|
19
|
+
* 123 // invalid value - should be a string
|
|
20
|
+
* );
|
|
21
|
+
* // Error: Avalon configuration error in 'islandsDir': must be a valid directory path
|
|
22
|
+
* // Received value: 123
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class AvalonConfigError extends Error {
|
|
26
|
+
/**
|
|
27
|
+
* The name of the configuration field that caused the error
|
|
28
|
+
*/
|
|
29
|
+
readonly field: string;
|
|
30
|
+
/**
|
|
31
|
+
* The invalid value that was provided
|
|
32
|
+
*/
|
|
33
|
+
readonly value: unknown;
|
|
34
|
+
constructor(message: string, field: string, value: unknown);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Thrown when an integration fails to load or has an invalid name
|
|
38
|
+
*
|
|
39
|
+
* This error includes the integration name and optionally the underlying cause,
|
|
40
|
+
* making it easier to diagnose integration loading issues.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* throw new IntegrationError(
|
|
45
|
+
* "Failed to activate integration. Is @useavalon/react installed?",
|
|
46
|
+
* "react",
|
|
47
|
+
* originalError
|
|
48
|
+
* );
|
|
49
|
+
* // Error: Integration 'react': Failed to activate integration. Is @useavalon/react installed?
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare class IntegrationError extends Error {
|
|
53
|
+
/**
|
|
54
|
+
* The name of the integration that caused the error
|
|
55
|
+
*/
|
|
56
|
+
readonly integrationName: string;
|
|
57
|
+
/**
|
|
58
|
+
* The original error that caused this error, if any
|
|
59
|
+
*/
|
|
60
|
+
readonly originalCause?: Error;
|
|
61
|
+
constructor(message: string, integrationName: string, originalCause?: Error);
|
|
62
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Optimization Plugin for Avalon
|
|
3
|
+
*
|
|
4
|
+
* Wraps vite-imagetools to provide automatic image optimization with
|
|
5
|
+
* sensible defaults for responsive images, modern formats, and srcset generation.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Automatic WebP/AVIF conversion
|
|
9
|
+
* - Responsive srcset generation at multiple breakpoints
|
|
10
|
+
* - Metadata stripping for privacy
|
|
11
|
+
* - JSX component output for easy usage in islands
|
|
12
|
+
*
|
|
13
|
+
* Usage in components:
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Basic - returns optimized URL
|
|
16
|
+
* import heroImg from './hero.jpg?w=800&format=webp';
|
|
17
|
+
*
|
|
18
|
+
* // With srcset for responsive images
|
|
19
|
+
* import heroImg from './hero.jpg?w=400;800;1200&format=webp&as=srcset';
|
|
20
|
+
*
|
|
21
|
+
* // As JSX component (like Qwik's ?jsx)
|
|
22
|
+
* import HeroImage from './hero.jpg?w=1200&jsx';
|
|
23
|
+
* <HeroImage alt="Hero" />
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { Plugin } from 'vite';
|
|
27
|
+
import type { ResolvedImageConfig } from './types.ts';
|
|
28
|
+
/**
|
|
29
|
+
* Creates the vite-imagetools plugin with Avalon's configuration
|
|
30
|
+
*/
|
|
31
|
+
export declare function createImagePlugin(config: ResolvedImageConfig, verbose: boolean): Promise<Plugin[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Type declarations for image imports
|
|
34
|
+
* Users can reference these in their tsconfig.json
|
|
35
|
+
*/
|
|
36
|
+
export declare const IMAGE_TYPES_DECLARATION = "\ndeclare module '*.jpg' {\n const src: string;\n export default src;\n}\n\ndeclare module '*.jpeg' {\n const src: string;\n export default src;\n}\n\ndeclare module '*.png' {\n const src: string;\n export default src;\n}\n\ndeclare module '*.webp' {\n const src: string;\n export default src;\n}\n\ndeclare module '*.avif' {\n const src: string;\n export default src;\n}\n\ndeclare module '*.gif' {\n const src: string;\n export default src;\n}\n\ndeclare module '*?jsx' {\n import type { ComponentType } from 'preact';\n const Component: ComponentType<{ alt: string; class?: string; style?: Record<string, string> }>;\n export default Component;\n}\n\ndeclare module '*&jsx' {\n import type { ComponentType } from 'preact';\n const Component: ComponentType<{ alt: string; class?: string; style?: Record<string, string> }>;\n export default Component;\n}\n";
|