@useavalon/avalon 0.1.13 → 0.1.14
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.js +1 -0
- package/dist/src/build/integration-bundler-plugin.js +1 -0
- package/dist/src/build/integration-config.js +1 -0
- package/dist/src/build/integration-detection-plugin.js +1 -0
- package/dist/src/build/integration-resolver-plugin.js +1 -0
- package/dist/src/build/island-manifest.js +1 -0
- package/dist/src/build/island-types-generator.js +5 -0
- package/dist/src/build/mdx-island-transform.js +2 -0
- package/dist/src/build/mdx-plugin.js +1 -0
- package/dist/src/build/page-island-transform.js +3 -0
- package/dist/src/build/prop-extractors/index.js +1 -0
- package/dist/src/build/prop-extractors/lit.js +1 -0
- package/dist/src/build/prop-extractors/qwik.js +1 -0
- package/dist/src/build/prop-extractors/solid.js +1 -0
- package/dist/src/build/prop-extractors/svelte.js +1 -0
- package/dist/src/build/prop-extractors/vue.js +1 -0
- package/dist/src/build/sidecar-file-manager.js +1 -0
- package/dist/src/build/sidecar-renderer.js +6 -0
- package/dist/src/client/adapters/index.js +1 -0
- package/dist/src/client/components.js +1 -0
- package/dist/src/client/css-hmr-handler.js +1 -0
- package/dist/src/client/framework-adapter.js +13 -0
- package/dist/src/client/hmr-coordinator.js +1 -0
- package/dist/src/client/hmr-error-overlay.js +214 -0
- package/dist/src/client/main.js +39 -0
- package/dist/src/components/Image.js +1 -0
- package/dist/src/components/IslandErrorBoundary.js +1 -0
- package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
- package/dist/src/components/LayoutErrorBoundary.js +1 -0
- package/dist/src/components/PersistentIsland.js +1 -0
- package/dist/src/components/StreamingErrorBoundary.js +1 -0
- package/dist/src/components/StreamingLayout.js +29 -0
- package/dist/src/core/components/component-analyzer.js +1 -0
- package/dist/src/core/components/component-detection.js +5 -0
- package/dist/src/core/components/enhanced-framework-detector.js +1 -0
- package/dist/src/core/components/framework-registry.js +1 -0
- package/dist/src/core/content/mdx-processor.js +1 -0
- package/dist/src/core/integrations/index.js +1 -0
- package/dist/src/core/integrations/loader.js +1 -0
- package/dist/src/core/integrations/registry.js +1 -0
- package/dist/src/core/islands/island-persistence.js +1 -0
- package/dist/src/core/islands/island-state-serializer.js +1 -0
- package/dist/src/core/islands/persistent-island-context.js +1 -0
- package/dist/src/core/islands/use-persistent-state.js +1 -0
- package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
- package/dist/src/core/layout/layout-cache-manager.js +1 -0
- package/dist/src/core/layout/layout-composer.js +1 -0
- package/dist/src/core/layout/layout-data-loader.js +1 -0
- package/dist/src/core/layout/layout-discovery.js +1 -0
- package/dist/src/core/layout/layout-matcher.js +1 -0
- package/dist/src/core/layout/layout-types.js +1 -0
- package/dist/src/core/modules/framework-module-resolver.js +1 -0
- package/dist/src/islands/component-analysis.js +1 -0
- package/dist/src/islands/css-utils.js +17 -0
- package/dist/src/islands/discovery/index.js +1 -0
- package/dist/src/islands/discovery/registry.js +1 -0
- package/dist/src/islands/discovery/resolver.js +2 -0
- package/dist/src/islands/discovery/scanner.js +1 -0
- package/dist/src/islands/discovery/types.js +1 -0
- package/dist/src/islands/discovery/validator.js +18 -0
- package/dist/src/islands/discovery/watcher.js +1 -0
- package/dist/src/islands/framework-detection.js +1 -0
- package/dist/src/islands/integration-loader.js +1 -0
- package/dist/src/islands/island.js +1 -0
- package/dist/src/islands/render-cache.js +1 -0
- package/dist/src/islands/types.js +1 -0
- package/dist/src/islands/universal-css-collector.js +5 -0
- package/dist/src/islands/universal-head-collector.js +2 -0
- package/dist/src/layout-system.js +1 -0
- package/dist/src/middleware/discovery.js +1 -0
- package/dist/src/middleware/executor.js +1 -0
- package/dist/src/middleware/index.js +1 -0
- package/dist/src/middleware/types.js +1 -0
- package/dist/src/nitro/build-config.js +1 -0
- package/dist/src/nitro/config.js +1 -0
- package/dist/src/nitro/error-handler.js +198 -0
- package/dist/src/nitro/index.js +1 -0
- package/dist/src/nitro/island-manifest.js +2 -0
- package/dist/src/nitro/middleware-adapter.js +1 -0
- package/dist/src/nitro/renderer.js +183 -0
- package/dist/src/nitro/route-discovery.js +1 -0
- package/dist/src/nitro/types.js +1 -0
- package/dist/src/render/collect-css.js +3 -0
- package/dist/src/render/error-pages.js +48 -0
- package/dist/src/render/isolated-ssr-renderer.js +1 -0
- package/dist/src/render/ssr.js +90 -0
- package/dist/src/schemas/api.js +1 -0
- package/dist/src/schemas/core.js +1 -0
- package/dist/src/schemas/index.js +1 -0
- package/dist/src/schemas/layout.js +1 -0
- package/dist/src/schemas/routing/index.js +1 -0
- package/dist/src/schemas/routing.js +1 -0
- package/dist/src/types/as-island.js +1 -0
- package/dist/src/types/layout.js +1 -0
- package/dist/src/types/routing.js +1 -0
- package/dist/src/types/types.js +1 -0
- package/dist/src/utils/dev-logger.js +12 -0
- package/dist/src/utils/fs.js +1 -0
- package/dist/src/vite-plugin/auto-discover.js +1 -0
- package/dist/src/vite-plugin/config.js +1 -0
- package/dist/src/vite-plugin/errors.js +1 -0
- package/dist/src/vite-plugin/image-optimization.js +45 -0
- package/dist/src/vite-plugin/integration-activator.js +1 -0
- package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
- package/dist/src/vite-plugin/module-discovery.js +1 -0
- package/dist/src/vite-plugin/nitro-integration.js +42 -0
- package/dist/src/vite-plugin/plugin.js +1 -0
- package/dist/src/vite-plugin/types.js +1 -0
- package/dist/src/vite-plugin/validation.js +2 -0
- package/package.json +14 -20
- package/mod.ts +0 -302
- package/src/build/integration-bundler-plugin.ts +0 -116
- package/src/build/integration-config.ts +0 -168
- package/src/build/integration-detection-plugin.ts +0 -117
- package/src/build/integration-resolver-plugin.ts +0 -90
- package/src/build/island-manifest.ts +0 -269
- package/src/build/island-types-generator.ts +0 -476
- package/src/build/mdx-island-transform.ts +0 -464
- package/src/build/mdx-plugin.ts +0 -98
- package/src/build/page-island-transform.ts +0 -598
- package/src/build/prop-extractors/index.ts +0 -21
- package/src/build/prop-extractors/lit.ts +0 -140
- package/src/build/prop-extractors/qwik.ts +0 -16
- package/src/build/prop-extractors/solid.ts +0 -125
- package/src/build/prop-extractors/svelte.ts +0 -194
- package/src/build/prop-extractors/vue.ts +0 -111
- package/src/build/sidecar-file-manager.ts +0 -104
- package/src/build/sidecar-renderer.ts +0 -30
- package/src/client/adapters/index.ts +0 -21
- package/src/client/components.ts +0 -35
- package/src/client/css-hmr-handler.ts +0 -344
- package/src/client/framework-adapter.ts +0 -462
- package/src/client/hmr-coordinator.ts +0 -396
- package/src/client/hmr-error-overlay.js +0 -533
- package/src/client/main.js +0 -824
- package/src/components/Image.tsx +0 -123
- package/src/components/IslandErrorBoundary.tsx +0 -145
- package/src/components/LayoutDataErrorBoundary.tsx +0 -141
- package/src/components/LayoutErrorBoundary.tsx +0 -127
- package/src/components/PersistentIsland.tsx +0 -52
- package/src/components/StreamingErrorBoundary.tsx +0 -233
- package/src/components/StreamingLayout.tsx +0 -538
- package/src/core/components/component-analyzer.ts +0 -192
- package/src/core/components/component-detection.ts +0 -508
- package/src/core/components/enhanced-framework-detector.ts +0 -500
- package/src/core/components/framework-registry.ts +0 -563
- package/src/core/content/mdx-processor.ts +0 -46
- package/src/core/integrations/index.ts +0 -19
- package/src/core/integrations/loader.ts +0 -125
- package/src/core/integrations/registry.ts +0 -175
- package/src/core/islands/island-persistence.ts +0 -325
- package/src/core/islands/island-state-serializer.ts +0 -258
- package/src/core/islands/persistent-island-context.tsx +0 -80
- package/src/core/islands/use-persistent-state.ts +0 -68
- package/src/core/layout/enhanced-layout-resolver.ts +0 -322
- package/src/core/layout/layout-cache-manager.ts +0 -485
- package/src/core/layout/layout-composer.ts +0 -357
- package/src/core/layout/layout-data-loader.ts +0 -516
- package/src/core/layout/layout-discovery.ts +0 -243
- package/src/core/layout/layout-matcher.ts +0 -299
- package/src/core/layout/layout-types.ts +0 -110
- package/src/core/modules/framework-module-resolver.ts +0 -273
- package/src/islands/component-analysis.ts +0 -213
- package/src/islands/css-utils.ts +0 -565
- package/src/islands/discovery/index.ts +0 -80
- package/src/islands/discovery/registry.ts +0 -340
- package/src/islands/discovery/resolver.ts +0 -477
- package/src/islands/discovery/scanner.ts +0 -386
- package/src/islands/discovery/types.ts +0 -117
- package/src/islands/discovery/validator.ts +0 -544
- package/src/islands/discovery/watcher.ts +0 -368
- package/src/islands/framework-detection.ts +0 -428
- package/src/islands/integration-loader.ts +0 -490
- package/src/islands/island.tsx +0 -565
- package/src/islands/render-cache.ts +0 -550
- package/src/islands/types.ts +0 -80
- package/src/islands/universal-css-collector.ts +0 -157
- package/src/islands/universal-head-collector.ts +0 -137
- package/src/layout-system.ts +0 -218
- package/src/middleware/discovery.ts +0 -268
- package/src/middleware/executor.ts +0 -315
- package/src/middleware/index.ts +0 -76
- package/src/middleware/types.ts +0 -99
- package/src/nitro/build-config.ts +0 -576
- package/src/nitro/config.ts +0 -483
- package/src/nitro/error-handler.ts +0 -636
- package/src/nitro/index.ts +0 -173
- package/src/nitro/island-manifest.ts +0 -584
- package/src/nitro/middleware-adapter.ts +0 -260
- package/src/nitro/renderer.ts +0 -1471
- package/src/nitro/route-discovery.ts +0 -439
- package/src/nitro/types.ts +0 -321
- package/src/render/collect-css.ts +0 -198
- package/src/render/error-pages.ts +0 -79
- package/src/render/isolated-ssr-renderer.ts +0 -654
- package/src/render/ssr.ts +0 -1030
- package/src/schemas/api.ts +0 -30
- package/src/schemas/core.ts +0 -64
- package/src/schemas/index.ts +0 -212
- package/src/schemas/layout.ts +0 -279
- package/src/schemas/routing/index.ts +0 -38
- package/src/schemas/routing.ts +0 -376
- package/src/types/as-island.ts +0 -20
- package/src/types/layout.ts +0 -285
- package/src/types/routing.ts +0 -555
- package/src/types/types.ts +0 -5
- package/src/utils/dev-logger.ts +0 -299
- package/src/utils/fs.ts +0 -151
- package/src/vite-plugin/auto-discover.ts +0 -551
- package/src/vite-plugin/config.ts +0 -266
- package/src/vite-plugin/errors.ts +0 -127
- package/src/vite-plugin/image-optimization.ts +0 -156
- package/src/vite-plugin/integration-activator.ts +0 -126
- package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
- package/src/vite-plugin/module-discovery.ts +0 -189
- package/src/vite-plugin/nitro-integration.ts +0 -1354
- package/src/vite-plugin/plugin.ts +0 -403
- package/src/vite-plugin/types.ts +0 -327
- package/src/vite-plugin/validation.ts +0 -228
- /package/{src → dist/src}/client/types/framework-runtime.d.ts +0 -0
- /package/{src → dist/src}/client/types/vite-hmr.d.ts +0 -0
- /package/{src → dist/src}/client/types/vite-virtual-modules.d.ts +0 -0
- /package/{src → dist/src}/layout-system.d.ts +0 -0
- /package/{src → dist/src}/types/image.d.ts +0 -0
- /package/{src → dist/src}/types/index.d.ts +0 -0
- /package/{src → dist/src}/types/island-jsx.d.ts +0 -0
- /package/{src → dist/src}/types/island-prop.d.ts +0 -0
- /package/{src → dist/src}/types/mdx.d.ts +0 -0
- /package/{src → dist/src}/types/urlpattern.d.ts +0 -0
- /package/{src → dist/src}/types/vite-env.d.ts +0 -0
package/src/types/routing.ts
DELETED
|
@@ -1,555 +0,0 @@
|
|
|
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
|
-
|
|
8
|
-
import type { ComponentType } from 'preact';
|
|
9
|
-
import { h } from 'preact';
|
|
10
|
-
import type {
|
|
11
|
-
LoaderContext,
|
|
12
|
-
Metadata
|
|
13
|
-
} from '../schemas/routing.ts';
|
|
14
|
-
import type { LayoutConfig } from '../schemas/layout.ts';
|
|
15
|
-
import process from "node:process";
|
|
16
|
-
|
|
17
|
-
// === Route Parameter Type Extraction ===
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Extract route parameters from a route pattern string
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* type BlogParams = ExtractRouteParams<'/blog/[slug]'>; // { slug: string }
|
|
25
|
-
* type UserParams = ExtractRouteParams<'/users/[id]/posts/[postId]'>; // { id: string; postId: string }
|
|
26
|
-
* type CatchAllParams = ExtractRouteParams<'/docs/[...path]'>; // { path: string[] }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export type ExtractRouteParams<T extends string> = T extends `${string}[${infer Param}]${infer Rest}`
|
|
30
|
-
? Param extends `...${infer RestParam}`
|
|
31
|
-
? { [K in RestParam]: string[] } & ExtractRouteParams<Rest>
|
|
32
|
-
: Param extends `${infer OptionalParam}?`
|
|
33
|
-
? { [K in OptionalParam]?: string } & ExtractRouteParams<Rest>
|
|
34
|
-
: { [K in Param]: string } & ExtractRouteParams<Rest>
|
|
35
|
-
: Record<PropertyKey, never>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Extract optional route parameters from a route pattern string
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```typescript
|
|
42
|
-
* type OptionalParams = ExtractOptionalParams<'/blog/[[...slug]]'>; // { slug?: string[] }
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export type ExtractOptionalParams<T extends string> = T extends `${string}[[${infer Param}]]${infer Rest}`
|
|
46
|
-
? Param extends `...${infer RestParam}`
|
|
47
|
-
? { [K in RestParam]?: string[] } & ExtractOptionalParams<Rest>
|
|
48
|
-
: { [K in Param]?: string } & ExtractOptionalParams<Rest>
|
|
49
|
-
: Record<PropertyKey, never>;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Combine required and optional route parameters
|
|
53
|
-
*/
|
|
54
|
-
export type RouteParameters<T extends string> = ExtractRouteParams<T> & ExtractOptionalParams<T>;
|
|
55
|
-
|
|
56
|
-
// === Strongly Typed Page Components ===
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Strongly typed page component with route parameters
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```typescript
|
|
63
|
-
* const BlogPost: TypedPageComponent<'/blog/[slug]'> = ({ params, query, data }) => {
|
|
64
|
-
* // params.slug is typed as string
|
|
65
|
-
* return <div>Blog post: {params.slug}</div>;
|
|
66
|
-
* };
|
|
67
|
-
* ```
|
|
68
|
-
*/
|
|
69
|
-
export type TypedPageComponent<TRoute extends string = string> = ComponentType<{
|
|
70
|
-
params: RouteParameters<TRoute>;
|
|
71
|
-
query: URLSearchParams;
|
|
72
|
-
data?: unknown;
|
|
73
|
-
}>;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Page component with custom data type
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```typescript
|
|
80
|
-
* interface BlogPostData {
|
|
81
|
-
* title: string;
|
|
82
|
-
* content: string;
|
|
83
|
-
* }
|
|
84
|
-
*
|
|
85
|
-
* const BlogPost: TypedPageComponentWithData<'/blog/[slug]', BlogPostData> = ({ params, data }) => {
|
|
86
|
-
* // data is typed as BlogPostData | undefined
|
|
87
|
-
* return <div>{data?.title}</div>;
|
|
88
|
-
* };
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
export type TypedPageComponentWithData<TRoute extends string, TData> = ComponentType<{
|
|
92
|
-
params: RouteParameters<TRoute>;
|
|
93
|
-
query: URLSearchParams;
|
|
94
|
-
data?: TData;
|
|
95
|
-
}>;
|
|
96
|
-
|
|
97
|
-
// === Strongly Typed Metadata Generators ===
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Strongly typed metadata generator function
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* ```typescript
|
|
104
|
-
* const generateMetadata: TypedMetadataGenerator<'/blog/[slug]'> = async ({ slug }) => {
|
|
105
|
-
* // slug is typed as string
|
|
106
|
-
* return {
|
|
107
|
-
* title: `Blog Post: ${slug}`,
|
|
108
|
-
* description: `Read about ${slug}`,
|
|
109
|
-
* };
|
|
110
|
-
* };
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
113
|
-
export type TypedMetadataGenerator<TRoute extends string> = (params: RouteParameters<TRoute>) => Promise<Metadata>;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Metadata generator with custom context
|
|
117
|
-
*/
|
|
118
|
-
export type TypedMetadataGeneratorWithContext<TRoute extends string, TContext = unknown> = (
|
|
119
|
-
params: RouteParameters<TRoute>,
|
|
120
|
-
context: TContext
|
|
121
|
-
) => Promise<Metadata>;
|
|
122
|
-
|
|
123
|
-
// === Strongly Typed Page Loaders ===
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Strongly typed page loader function
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
129
|
-
* ```typescript
|
|
130
|
-
* const loader: TypedPageLoader<'/blog/[slug]', BlogPostData> = async ({ params, request }) => {
|
|
131
|
-
* // params.slug is typed as string
|
|
132
|
-
* const post = await fetchBlogPost(params.slug);
|
|
133
|
-
* return post;
|
|
134
|
-
* };
|
|
135
|
-
* ```
|
|
136
|
-
*/
|
|
137
|
-
export type TypedPageLoader<TRoute extends string, TData = unknown> = (
|
|
138
|
-
context: LoaderContext & { params: RouteParameters<TRoute> }
|
|
139
|
-
) => Promise<TData>;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Page loader with custom context
|
|
143
|
-
*/
|
|
144
|
-
export type TypedPageLoaderWithContext<TRoute extends string, TData = unknown, TContext = unknown> = (
|
|
145
|
-
context: LoaderContext & { params: RouteParameters<TRoute> },
|
|
146
|
-
customContext: TContext
|
|
147
|
-
) => Promise<TData>;
|
|
148
|
-
|
|
149
|
-
// === Strongly Typed Route Modules ===
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Strongly typed route page module
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```typescript
|
|
156
|
-
* const pageModule: TypedRoutePageModule<'/blog/[slug]', BlogPostData> = {
|
|
157
|
-
* default: BlogPostComponent,
|
|
158
|
-
* generateMetadata: async ({ slug }) => ({ title: slug }),
|
|
159
|
-
* loader: async ({ params }) => fetchBlogPost(params.slug),
|
|
160
|
-
* };
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
export type TypedRoutePageModule<TRoute extends string, TData = unknown> = {
|
|
164
|
-
default: TypedPageComponent<TRoute>;
|
|
165
|
-
layoutConfig?: LayoutConfig;
|
|
166
|
-
generateMetadata?: TypedMetadataGenerator<TRoute>;
|
|
167
|
-
loader?: TypedPageLoader<TRoute, TData>;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
// === API Route Types ===
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Strongly typed API handler function
|
|
174
|
-
*
|
|
175
|
-
* @example
|
|
176
|
-
* ```typescript
|
|
177
|
-
* export const GET: TypedApiHandler<'/api/users/[id]'> = async (request, { params }) => {
|
|
178
|
-
* // params.id is typed as string
|
|
179
|
-
* const user = await getUser(params.id);
|
|
180
|
-
* return Response.json(user);
|
|
181
|
-
* };
|
|
182
|
-
* ```
|
|
183
|
-
*/
|
|
184
|
-
export type TypedApiHandler<TRoute extends string> = (
|
|
185
|
-
request: Request,
|
|
186
|
-
context: LoaderContext & { params: RouteParameters<TRoute> }
|
|
187
|
-
) => Promise<Response>;
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Strongly typed API module with all HTTP methods
|
|
191
|
-
*/
|
|
192
|
-
export type TypedApiModule<TRoute extends string> = {
|
|
193
|
-
GET?: TypedApiHandler<TRoute>;
|
|
194
|
-
POST?: TypedApiHandler<TRoute>;
|
|
195
|
-
PUT?: TypedApiHandler<TRoute>;
|
|
196
|
-
DELETE?: TypedApiHandler<TRoute>;
|
|
197
|
-
PATCH?: TypedApiHandler<TRoute>;
|
|
198
|
-
HEAD?: TypedApiHandler<TRoute>;
|
|
199
|
-
OPTIONS?: TypedApiHandler<TRoute>;
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// === Route Validation Types ===
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Route pattern validation
|
|
206
|
-
*/
|
|
207
|
-
export type ValidRoutePattern<T extends string> = T extends `${string}[${string}]${string}`
|
|
208
|
-
? T
|
|
209
|
-
: T extends `${string}(${string})${string}`
|
|
210
|
-
? T
|
|
211
|
-
: T extends `${string}_${string}`
|
|
212
|
-
? never // Private files/folders
|
|
213
|
-
: T;
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Valid file extensions for routes
|
|
217
|
-
*/
|
|
218
|
-
export type ValidRouteExtension = '.tsx' | '.ts' | '.jsx' | '.js';
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Route file path validation
|
|
222
|
-
*/
|
|
223
|
-
export type ValidRouteFile<T extends string> = T extends `${string}${ValidRouteExtension}`
|
|
224
|
-
? T extends `${string}_${string}`
|
|
225
|
-
? never // Private files
|
|
226
|
-
: T
|
|
227
|
-
: never;
|
|
228
|
-
|
|
229
|
-
// === Component Prop Validation ===
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Validate that a component accepts the correct props for a route
|
|
233
|
-
*/
|
|
234
|
-
export type ValidatePageComponent<TRoute extends string, TComponent> = TComponent extends ComponentType<infer TProps>
|
|
235
|
-
? TProps extends { params: RouteParameters<TRoute> }
|
|
236
|
-
? TComponent
|
|
237
|
-
: never
|
|
238
|
-
: never;
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Props validation for page components
|
|
242
|
-
*/
|
|
243
|
-
export interface PageComponentProps<TRoute extends string = string, TData = unknown> {
|
|
244
|
-
params: RouteParameters<TRoute>;
|
|
245
|
-
query: URLSearchParams;
|
|
246
|
-
data?: TData;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Validate page component props
|
|
251
|
-
*/
|
|
252
|
-
export type ValidatePageProps<TRoute extends string, TProps> = TProps extends PageComponentProps<TRoute>
|
|
253
|
-
? TProps
|
|
254
|
-
: never;
|
|
255
|
-
|
|
256
|
-
// === Utility Types for Route Analysis ===
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Check if a route has dynamic segments
|
|
260
|
-
*/
|
|
261
|
-
export type HasDynamicSegments<T extends string> = T extends `${string}[${string}]${string}` ? true : false;
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Check if a route has catch-all segments
|
|
265
|
-
*/
|
|
266
|
-
export type HasCatchAllSegments<T extends string> = T extends `${string}[...${string}]${string}` ? true : false;
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Check if a route has optional segments
|
|
270
|
-
*/
|
|
271
|
-
export type HasOptionalSegments<T extends string> = T extends `${string}[[${string}]]${string}` ? true : false;
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Get the static parts of a route
|
|
275
|
-
*/
|
|
276
|
-
export type GetStaticParts<T extends string> = T extends `${infer Static}[${string}]${infer Rest}`
|
|
277
|
-
? Static | GetStaticParts<Rest>
|
|
278
|
-
: T;
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Count dynamic segments in a route
|
|
282
|
-
*/
|
|
283
|
-
export type CountDynamicSegments<
|
|
284
|
-
T extends string,
|
|
285
|
-
Count extends readonly unknown[] = []
|
|
286
|
-
> = T extends `${string}[${string}]${infer Rest}` ? CountDynamicSegments<Rest, [...Count, unknown]> : Count['length'];
|
|
287
|
-
|
|
288
|
-
// === Error Handling Types ===
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Route error types
|
|
292
|
-
*/
|
|
293
|
-
export type RouteErrorType =
|
|
294
|
-
| 'ROUTE_NOT_FOUND'
|
|
295
|
-
| 'INVALID_PARAMS'
|
|
296
|
-
| 'LOADER_ERROR'
|
|
297
|
-
| 'METADATA_ERROR'
|
|
298
|
-
| 'COMPONENT_ERROR'
|
|
299
|
-
| 'VALIDATION_ERROR';
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Route error with context
|
|
303
|
-
*/
|
|
304
|
-
export interface RouteError<TRoute extends string = string> {
|
|
305
|
-
type: RouteErrorType;
|
|
306
|
-
route: TRoute;
|
|
307
|
-
params?: Partial<RouteParameters<TRoute>>;
|
|
308
|
-
message: string;
|
|
309
|
-
originalError?: Error;
|
|
310
|
-
suggestions?: string[];
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Error boundary props for routes
|
|
315
|
-
*/
|
|
316
|
-
export interface RouteErrorBoundaryProps<TRoute extends string = string> {
|
|
317
|
-
error: RouteError<TRoute>;
|
|
318
|
-
retry: () => void;
|
|
319
|
-
fallback?: ComponentType<{ error: RouteError<TRoute> }>;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// === Development and Debugging Types ===
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Route debugging information
|
|
326
|
-
*/
|
|
327
|
-
export interface RouteDebugInfo<TRoute extends string = string> {
|
|
328
|
-
route: TRoute;
|
|
329
|
-
params: RouteParameters<TRoute>;
|
|
330
|
-
staticParts: string[];
|
|
331
|
-
dynamicSegments: string[];
|
|
332
|
-
hasOptionalSegments: HasOptionalSegments<TRoute>;
|
|
333
|
-
hasCatchAllSegments: HasCatchAllSegments<TRoute>;
|
|
334
|
-
priority: number;
|
|
335
|
-
filePath: string;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Route performance metrics
|
|
340
|
-
*/
|
|
341
|
-
export interface RoutePerformanceMetrics {
|
|
342
|
-
discoveryTime: number;
|
|
343
|
-
loadTime: number;
|
|
344
|
-
renderTime: number;
|
|
345
|
-
metadataResolutionTime: number;
|
|
346
|
-
cacheHits: number;
|
|
347
|
-
cacheMisses: number;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// === Type Guards and Validation Functions ===
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Type guard for route parameters
|
|
354
|
-
*/
|
|
355
|
-
export function isValidRouteParams<TRoute extends string>(
|
|
356
|
-
params: unknown,
|
|
357
|
-
expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
358
|
-
): params is RouteParameters<TRoute> {
|
|
359
|
-
if (!params || typeof params !== 'object') {
|
|
360
|
-
return false;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const paramObj = params as Record<string, unknown>;
|
|
364
|
-
|
|
365
|
-
// Check that all expected parameters are present and are strings or string arrays
|
|
366
|
-
for (const param of expectedParams) {
|
|
367
|
-
const value = paramObj[param as string];
|
|
368
|
-
if (value === undefined) {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
if (typeof value !== 'string' && !Array.isArray(value)) {
|
|
372
|
-
return false;
|
|
373
|
-
}
|
|
374
|
-
if (Array.isArray(value) && !value.every(item => typeof item === 'string')) {
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return true;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Type guard for page component props
|
|
384
|
-
*/
|
|
385
|
-
export function isValidPageProps<TRoute extends string>(
|
|
386
|
-
props: unknown,
|
|
387
|
-
expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
388
|
-
): props is PageComponentProps<TRoute> {
|
|
389
|
-
if (!props || typeof props !== 'object') {
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
const propsObj = props as Record<string, unknown>;
|
|
394
|
-
|
|
395
|
-
// Check required properties
|
|
396
|
-
if (!propsObj.params || !propsObj.query) {
|
|
397
|
-
return false;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Validate params
|
|
401
|
-
if (!isValidRouteParams<TRoute>(propsObj.params, expectedParams)) {
|
|
402
|
-
return false;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// Validate query
|
|
406
|
-
if (!(propsObj.query instanceof URLSearchParams)) {
|
|
407
|
-
return false;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
return true;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Validate route pattern syntax
|
|
415
|
-
*/
|
|
416
|
-
export function isValidRoutePattern(pattern: string): boolean {
|
|
417
|
-
// Check for valid bracket syntax
|
|
418
|
-
const bracketRegex = /\[([^\]]+)\]/g;
|
|
419
|
-
const matches = pattern.match(bracketRegex);
|
|
420
|
-
|
|
421
|
-
if (matches) {
|
|
422
|
-
for (const match of matches) {
|
|
423
|
-
const param = match.slice(1, -1); // Remove brackets
|
|
424
|
-
|
|
425
|
-
// Check for valid parameter names
|
|
426
|
-
if (!/^[a-zA-Z_]\w*(\?)?$/.test(param) && !/^\.\.\.[a-zA-Z_]\w*$/.test(param)) {
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// Check for valid route group syntax
|
|
433
|
-
const groupRegex = /\(([^)]+)\)/g;
|
|
434
|
-
const groupMatches = pattern.match(groupRegex);
|
|
435
|
-
|
|
436
|
-
if (groupMatches) {
|
|
437
|
-
for (const match of groupMatches) {
|
|
438
|
-
const group = match.slice(1, -1); // Remove parentheses
|
|
439
|
-
|
|
440
|
-
// Check for valid group names
|
|
441
|
-
if (!/^[a-zA-Z_]\w*-*\w*$/.test(group)) {
|
|
442
|
-
return false;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
return true;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// === Helper Functions for Type Safety ===
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Create a typed page component with parameter validation
|
|
454
|
-
*/
|
|
455
|
-
export function createTypedPageComponent<TRoute extends string>(
|
|
456
|
-
component: TypedPageComponent<TRoute>,
|
|
457
|
-
expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
458
|
-
): TypedPageComponent<TRoute> {
|
|
459
|
-
// Return a wrapper component that validates props
|
|
460
|
-
const WrappedComponent: TypedPageComponent<TRoute> = (props) => {
|
|
461
|
-
if (process.env?.NODE_ENV === 'development') {
|
|
462
|
-
if (!isValidPageProps<TRoute>(props, expectedParams)) {
|
|
463
|
-
console.warn('Invalid props passed to typed page component:', props);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
return h(component, props);
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
return WrappedComponent;
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Create a typed metadata generator with parameter validation
|
|
474
|
-
*/
|
|
475
|
-
export function createTypedMetadataGenerator<TRoute extends string>(
|
|
476
|
-
generator: TypedMetadataGenerator<TRoute>,
|
|
477
|
-
expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
478
|
-
): TypedMetadataGenerator<TRoute> {
|
|
479
|
-
return async params => {
|
|
480
|
-
// Validate params in development
|
|
481
|
-
if (process.env?.NODE_ENV === 'development') {
|
|
482
|
-
if (!isValidRouteParams<TRoute>(params, expectedParams)) {
|
|
483
|
-
console.warn('Invalid params passed to typed metadata generator:', params);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
return await generator(params);
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Create a typed page loader with parameter validation
|
|
493
|
-
*/
|
|
494
|
-
export function createTypedPageLoader<TRoute extends string, TData = unknown>(
|
|
495
|
-
loader: TypedPageLoader<TRoute, TData>,
|
|
496
|
-
expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
497
|
-
): TypedPageLoader<TRoute, TData> {
|
|
498
|
-
return async context => {
|
|
499
|
-
// Validate params in development
|
|
500
|
-
if (process.env?.NODE_ENV === 'development') {
|
|
501
|
-
if (!isValidRouteParams<TRoute>(context.params, expectedParams)) {
|
|
502
|
-
console.warn('Invalid params passed to typed page loader:', context.params);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
return await loader(context);
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Validate component accepts correct props for a route
|
|
512
|
-
*/
|
|
513
|
-
export function validatePageComponent<TRoute extends string>(
|
|
514
|
-
component: unknown,
|
|
515
|
-
_expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
516
|
-
): component is TypedPageComponent<TRoute> {
|
|
517
|
-
// In TypeScript, we can't really validate function signatures at runtime
|
|
518
|
-
// This is more of a development-time helper
|
|
519
|
-
if (typeof component !== 'function') {
|
|
520
|
-
return false;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Could add more sophisticated validation in development mode
|
|
524
|
-
return true;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
/**
|
|
528
|
-
* Create a typed API handler with parameter validation
|
|
529
|
-
*/
|
|
530
|
-
export function createTypedApiHandler<TRoute extends string>(
|
|
531
|
-
handler: TypedApiHandler<TRoute>,
|
|
532
|
-
expectedParams: (keyof RouteParameters<TRoute>)[]
|
|
533
|
-
): TypedApiHandler<TRoute> {
|
|
534
|
-
return async (request, context) => {
|
|
535
|
-
// Validate params in development
|
|
536
|
-
if (process.env?.NODE_ENV === 'development') {
|
|
537
|
-
if (!isValidRouteParams<TRoute>(context.params, expectedParams)) {
|
|
538
|
-
console.warn('Invalid params passed to typed API handler:', context.params);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
return await handler(request, context);
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
// === Re-export commonly used types ===
|
|
547
|
-
export type {
|
|
548
|
-
RouteParams,
|
|
549
|
-
LoaderContext,
|
|
550
|
-
Metadata,
|
|
551
|
-
PageProps,
|
|
552
|
-
RoutePageModule,
|
|
553
|
-
FileSystemRoute,
|
|
554
|
-
ResolvedMetadata,
|
|
555
|
-
} from '../schemas/routing.ts';
|