@useavalon/avalon 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.md +54 -54
  2. package/mod.ts +302 -302
  3. package/package.json +49 -26
  4. package/src/build/integration-bundler-plugin.ts +116 -116
  5. package/src/build/integration-config.ts +168 -168
  6. package/src/build/integration-detection-plugin.ts +117 -117
  7. package/src/build/integration-resolver-plugin.ts +90 -90
  8. package/src/build/island-manifest.ts +269 -269
  9. package/src/build/island-types-generator.ts +476 -476
  10. package/src/build/mdx-island-transform.ts +464 -464
  11. package/src/build/mdx-plugin.ts +98 -98
  12. package/src/build/page-island-transform.ts +598 -598
  13. package/src/build/prop-extractors/index.ts +21 -21
  14. package/src/build/prop-extractors/lit.ts +140 -140
  15. package/src/build/prop-extractors/qwik.ts +16 -16
  16. package/src/build/prop-extractors/solid.ts +125 -125
  17. package/src/build/prop-extractors/svelte.ts +194 -194
  18. package/src/build/prop-extractors/vue.ts +111 -111
  19. package/src/build/sidecar-file-manager.ts +104 -104
  20. package/src/build/sidecar-renderer.ts +30 -30
  21. package/src/client/adapters/index.ts +21 -13
  22. package/src/client/components.ts +35 -35
  23. package/src/client/css-hmr-handler.ts +344 -344
  24. package/src/client/framework-adapter.ts +462 -462
  25. package/src/client/hmr-coordinator.ts +396 -396
  26. package/src/client/hmr-error-overlay.js +533 -533
  27. package/src/client/main.js +824 -816
  28. package/src/client/types/framework-runtime.d.ts +68 -68
  29. package/src/client/types/vite-hmr.d.ts +46 -46
  30. package/src/client/types/vite-virtual-modules.d.ts +70 -60
  31. package/src/components/Image.tsx +123 -123
  32. package/src/components/IslandErrorBoundary.tsx +145 -145
  33. package/src/components/LayoutDataErrorBoundary.tsx +141 -141
  34. package/src/components/LayoutErrorBoundary.tsx +127 -127
  35. package/src/components/PersistentIsland.tsx +52 -52
  36. package/src/components/StreamingErrorBoundary.tsx +233 -233
  37. package/src/components/StreamingLayout.tsx +538 -538
  38. package/src/core/components/component-analyzer.ts +192 -192
  39. package/src/core/components/component-detection.ts +508 -508
  40. package/src/core/components/enhanced-framework-detector.ts +500 -500
  41. package/src/core/components/framework-registry.ts +563 -563
  42. package/src/core/content/mdx-processor.ts +46 -46
  43. package/src/core/integrations/index.ts +19 -19
  44. package/src/core/integrations/loader.ts +125 -125
  45. package/src/core/integrations/registry.ts +175 -175
  46. package/src/core/islands/island-persistence.ts +325 -325
  47. package/src/core/islands/island-state-serializer.ts +258 -258
  48. package/src/core/islands/persistent-island-context.tsx +80 -80
  49. package/src/core/islands/use-persistent-state.ts +68 -68
  50. package/src/core/layout/enhanced-layout-resolver.ts +322 -322
  51. package/src/core/layout/layout-cache-manager.ts +485 -485
  52. package/src/core/layout/layout-composer.ts +357 -357
  53. package/src/core/layout/layout-data-loader.ts +516 -516
  54. package/src/core/layout/layout-discovery.ts +243 -243
  55. package/src/core/layout/layout-matcher.ts +299 -299
  56. package/src/core/layout/layout-types.ts +110 -110
  57. package/src/core/modules/framework-module-resolver.ts +273 -273
  58. package/src/islands/component-analysis.ts +213 -213
  59. package/src/islands/css-utils.ts +565 -565
  60. package/src/islands/discovery/index.ts +80 -80
  61. package/src/islands/discovery/registry.ts +340 -340
  62. package/src/islands/discovery/resolver.ts +477 -477
  63. package/src/islands/discovery/scanner.ts +386 -386
  64. package/src/islands/discovery/types.ts +117 -117
  65. package/src/islands/discovery/validator.ts +544 -544
  66. package/src/islands/discovery/watcher.ts +368 -368
  67. package/src/islands/framework-detection.ts +428 -428
  68. package/src/islands/integration-loader.ts +490 -490
  69. package/src/islands/island.tsx +565 -565
  70. package/src/islands/render-cache.ts +550 -550
  71. package/src/islands/types.ts +80 -80
  72. package/src/islands/universal-css-collector.ts +157 -157
  73. package/src/islands/universal-head-collector.ts +137 -137
  74. package/src/layout-system.d.ts +592 -592
  75. package/src/layout-system.ts +218 -218
  76. package/src/middleware/discovery.ts +268 -268
  77. package/src/middleware/executor.ts +315 -315
  78. package/src/middleware/index.ts +76 -76
  79. package/src/middleware/types.ts +99 -99
  80. package/src/nitro/build-config.ts +575 -575
  81. package/src/nitro/config.ts +483 -483
  82. package/src/nitro/error-handler.ts +636 -636
  83. package/src/nitro/index.ts +173 -173
  84. package/src/nitro/island-manifest.ts +584 -584
  85. package/src/nitro/middleware-adapter.ts +260 -260
  86. package/src/nitro/renderer.ts +1471 -1471
  87. package/src/nitro/route-discovery.ts +439 -439
  88. package/src/nitro/types.ts +321 -321
  89. package/src/render/collect-css.ts +198 -198
  90. package/src/render/error-pages.ts +79 -79
  91. package/src/render/isolated-ssr-renderer.ts +654 -654
  92. package/src/render/ssr.ts +1030 -1030
  93. package/src/schemas/api.ts +30 -30
  94. package/src/schemas/core.ts +64 -64
  95. package/src/schemas/index.ts +212 -212
  96. package/src/schemas/layout.ts +279 -279
  97. package/src/schemas/routing/index.ts +38 -38
  98. package/src/schemas/routing.ts +376 -376
  99. package/src/types/as-island.ts +20 -20
  100. package/src/types/image.d.ts +106 -106
  101. package/src/types/index.d.ts +22 -22
  102. package/src/types/island-jsx.d.ts +33 -33
  103. package/src/types/island-prop.d.ts +20 -20
  104. package/src/types/layout.ts +285 -285
  105. package/src/types/mdx.d.ts +6 -6
  106. package/src/types/routing.ts +555 -555
  107. package/src/types/types.ts +5 -5
  108. package/src/types/urlpattern.d.ts +49 -49
  109. package/src/types/vite-env.d.ts +11 -11
  110. package/src/utils/dev-logger.ts +299 -299
  111. package/src/utils/fs.ts +151 -151
  112. package/src/vite-plugin/auto-discover.ts +551 -551
  113. package/src/vite-plugin/config.ts +266 -266
  114. package/src/vite-plugin/errors.ts +127 -127
  115. package/src/vite-plugin/image-optimization.ts +156 -156
  116. package/src/vite-plugin/integration-activator.ts +126 -126
  117. package/src/vite-plugin/island-sidecar-plugin.ts +176 -176
  118. package/src/vite-plugin/module-discovery.ts +189 -189
  119. package/src/vite-plugin/nitro-integration.ts +1354 -1354
  120. package/src/vite-plugin/plugin.ts +403 -409
  121. package/src/vite-plugin/types.ts +327 -327
  122. package/src/vite-plugin/validation.ts +228 -228
  123. package/src/client/adapters/index.js +0 -12
  124. package/src/client/adapters/lit-adapter.js +0 -467
  125. package/src/client/adapters/lit-adapter.ts +0 -654
  126. package/src/client/adapters/preact-adapter.js +0 -223
  127. package/src/client/adapters/preact-adapter.ts +0 -331
  128. package/src/client/adapters/qwik-adapter.js +0 -259
  129. package/src/client/adapters/qwik-adapter.ts +0 -345
  130. package/src/client/adapters/react-adapter.js +0 -220
  131. package/src/client/adapters/react-adapter.ts +0 -353
  132. package/src/client/adapters/solid-adapter.js +0 -295
  133. package/src/client/adapters/solid-adapter.ts +0 -451
  134. package/src/client/adapters/svelte-adapter.js +0 -368
  135. package/src/client/adapters/svelte-adapter.ts +0 -524
  136. package/src/client/adapters/vue-adapter.js +0 -278
  137. package/src/client/adapters/vue-adapter.ts +0 -467
  138. package/src/client/components.js +0 -23
  139. package/src/client/css-hmr-handler.js +0 -263
  140. package/src/client/framework-adapter.js +0 -283
  141. package/src/client/hmr-coordinator.js +0 -274
@@ -1,376 +1,376 @@
1
- import { z } from 'zod';
2
- import type { ComponentType } from 'preact/compat';
3
-
4
- /**
5
- * Route Type Schema - Defines the different types of routes supported
6
- */
7
- export const RouteTypeSchema = z.enum(['static', 'dynamic', 'catch-all', 'index', 'group']);
8
-
9
- /**
10
- * File System Route Schema - Represents a discovered route from the file system
11
- */
12
- export const FileSystemRouteSchema = z.object({
13
- /** URL pattern for matching requests */
14
- pattern: z.any(), // URLPattern object - can't validate with Zod
15
- /** File path to the page component */
16
- filePath: z.string().min(1),
17
- /** Type of route (static, dynamic, etc.) */
18
- routeType: RouteTypeSchema,
19
- /** Dynamic segments extracted from the file path */
20
- dynamicSegments: z.array(z.string()),
21
- /** Route priority for conflict resolution (lower = higher priority) */
22
- priority: z.number().int().min(0),
23
- /** Whether this route is in a private folder */
24
- isPrivate: z.boolean(),
25
- /** Route group name if the route is in a group */
26
- routeGroup: z.string().optional(),
27
- });
28
-
29
- /**
30
- * Route Page Module Schema - Represents the exports from a page file in routing context
31
- */
32
- export const RoutePageModuleSchema = z.object({
33
- /** Default export - the page component */
34
- default: z.any(), // ComponentType<PageProps> - can't validate function types with Zod
35
- /** Optional layout configuration for this page */
36
- layoutConfig: z.any().optional(), // LayoutConfig from layout system
37
- /** Optional metadata generator function */
38
- generateMetadata: z.any().optional(), // (params: RouteParams) => Promise<Metadata>
39
- /** Optional data loader function */
40
- loader: z.any().optional(), // (context: LoaderContext) => Promise<any>
41
- /** Optional frontmatter data from MDX files */
42
- frontmatter: z.record(z.string(), z.any()).optional(), // Frontmatter metadata from MDX files
43
- });
44
-
45
- /**
46
- * Route Parameters Schema - Parameters extracted from dynamic routes
47
- */
48
- export const RouteParamsSchema = z.record(z.string(), z.string());
49
-
50
- /**
51
- * Loader Context Schema - Context passed to page loaders
52
- */
53
- export const LoaderContextSchema = z.object({
54
- /** HTTP request object */
55
- request: z.instanceof(Request),
56
- /** URL object for easy access */
57
- url: z.instanceof(URL),
58
- /** Route parameters */
59
- params: RouteParamsSchema,
60
- /** Query parameters */
61
- query: z.instanceof(URLSearchParams),
62
- /** State from middleware */
63
- state: z.instanceof(Map),
64
- });
65
-
66
- /**
67
- * Page Props Schema - Props passed to page components
68
- */
69
- export const PagePropsSchema = z.object({
70
- /** Route parameters */
71
- params: RouteParamsSchema,
72
- /** Query parameters */
73
- query: z.instanceof(URLSearchParams),
74
- /** Data from loader function */
75
- data: z.unknown().optional(),
76
- });
77
-
78
- /**
79
- * Metadata Schema - SEO and meta information
80
- */
81
- export const MetadataSchema = z.object({
82
- /** Page title */
83
- title: z.string().optional(),
84
- /** Page description */
85
- description: z.string().optional(),
86
- /** Keywords for SEO */
87
- keywords: z.array(z.string()).optional(),
88
- /** Open Graph data */
89
- openGraph: z
90
- .object({
91
- title: z.string().optional(),
92
- description: z.string().optional(),
93
- image: z.url().optional(),
94
- url: z.url().optional(),
95
- type: z.string().optional(),
96
- siteName: z.string().optional(),
97
- })
98
- .optional(),
99
- /** Twitter Card data */
100
- twitter: z
101
- .object({
102
- card: z.enum(['summary', 'summary_large_image', 'app', 'player']).optional(),
103
- title: z.string().optional(),
104
- description: z.string().optional(),
105
- image: z.url().optional(),
106
- site: z.string().optional(),
107
- })
108
- .optional(),
109
- /** Schema.org structured data */
110
- schema: z.array(z.record(z.string(), z.unknown())).optional(),
111
- /** Canonical URL */
112
- canonical: z.url().optional(),
113
- /** Robots meta tag */
114
- robots: z.string().optional(),
115
- });
116
-
117
- /**
118
- * Resolved Metadata Schema - Final merged metadata for a route
119
- */
120
- export const ResolvedMetadataSchema = MetadataSchema.extend({
121
- /** Source chain for debugging */
122
- sources: z.array(z.string()).optional(),
123
- /** Resolution timestamp */
124
- resolvedAt: z.number().optional(),
125
- });
126
-
127
- /**
128
- * Metadata Chain Schema - Hierarchical metadata from multiple sources
129
- */
130
- export const MetadataChainSchema = z.object({
131
- /** Global metadata */
132
- global: MetadataSchema.optional(),
133
- /** Section-specific metadata */
134
- sections: z.array(
135
- z.object({
136
- path: z.string(),
137
- metadata: MetadataSchema,
138
- })
139
- ),
140
- /** Page-specific metadata */
141
- page: MetadataSchema.optional(),
142
- });
143
-
144
- /**
145
- * Route Discovery Options Schema - Configuration for route discovery
146
- */
147
- export const RouteDiscoveryOptionsSchema = z.object({
148
- /** Base directory to scan for pages */
149
- pagesDirectory: z.string().min(1).default('src/pages'),
150
- /** Base directory to scan for API routes */
151
- apiDirectory: z.string().min(1).default('src/api'),
152
- /** File extensions to include */
153
- extensions: z.array(z.string()).default(['.tsx', '.ts', '.jsx', '.js']),
154
- /** Directories to exclude from scanning */
155
- excludeDirectories: z.array(z.string()).default(['node_modules', '.git']),
156
- /** Enable file watching for development */
157
- enableWatching: z.boolean().default(false),
158
- /** Development mode features */
159
- developmentMode: z.boolean().default(false),
160
- /** Quiet mode - suppress verbose logging */
161
- quietMode: z.boolean().default(false),
162
- });
163
-
164
- /**
165
- * File System Router Configuration Schema
166
- */
167
- export const FileSystemRouterConfigSchema = z.object({
168
- /** Route discovery options */
169
- discovery: RouteDiscoveryOptionsSchema.optional(),
170
- /** Enable file-system routing */
171
- enabled: z.boolean().default(true),
172
- /** Fallback to manual routes when file-system routes fail */
173
- fallbackToManual: z.boolean().default(true),
174
- /** Cache discovered routes */
175
- enableCaching: z.boolean().default(true),
176
- /** Cache TTL in milliseconds */
177
- cacheTTL: z.number().positive().default(300000), // 5 minutes
178
- });
179
-
180
- /**
181
- * Page File Schema - Information about a discovered page file
182
- */
183
- export const PageFileSchema = z.object({
184
- /** Absolute file path */
185
- filePath: z.string().min(1),
186
- /** Relative path from pages directory */
187
- relativePath: z.string().min(1),
188
- /** File extension */
189
- extension: z.string().min(1),
190
- /** Whether file is in a private folder */
191
- isPrivate: z.boolean(),
192
- /** Route group if applicable */
193
- routeGroup: z.string().optional(),
194
- /** File modification time */
195
- mtime: z.number().optional(),
196
- });
197
-
198
- /**
199
- * Route Handler Schema - Complete route handler information
200
- */
201
- export const RouteHandlerSchema = z.object({
202
- /** Route pattern */
203
- pattern: z.any(), // URLPattern
204
- /** Handler function */
205
- handler: z.any(), // (request: Request, context: LoaderContext) => Promise<Response>
206
- /** Route metadata */
207
- metadata: z.object({
208
- filePath: z.string(),
209
- routeType: RouteTypeSchema,
210
- priority: z.number(),
211
- dynamicSegments: z.array(z.string()),
212
- }),
213
- });
214
-
215
- /**
216
- * Route Cache Entry Schema - Cached route information
217
- */
218
- export const RouteCacheEntrySchema = z.object({
219
- /** Cached routes */
220
- routes: z.array(FileSystemRouteSchema),
221
- /** Cache timestamp */
222
- timestamp: z.number(),
223
- /** File modification times for cache invalidation */
224
- fileMtimes: z.record(z.string(), z.number()),
225
- });
226
-
227
- /**
228
- * File System API Route Schema - Represents an API endpoint route discovered from file system
229
- */
230
- export const FileSystemApiRouteSchema = z.object({
231
- /** URL pattern for the API endpoint */
232
- pattern: z.any(), // URLPattern
233
- /** File path to the API handler */
234
- filePath: z.string().min(1),
235
- /** HTTP methods supported */
236
- methods: z.array(z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'])),
237
- /** Route priority */
238
- priority: z.number().int().min(0),
239
- /** Dynamic segments */
240
- dynamicSegments: z.array(z.string()),
241
- });
242
-
243
- /**
244
- * File System API Module Schema - Exports from an API route file
245
- */
246
- export const FileSystemApiModuleSchema = z.object({
247
- /** GET handler */
248
- GET: z.any().optional(), // (request: Request, context: any) => Promise<Response>
249
- /** POST handler */
250
- POST: z.any().optional(),
251
- /** PUT handler */
252
- PUT: z.any().optional(),
253
- /** DELETE handler */
254
- DELETE: z.any().optional(),
255
- /** PATCH handler */
256
- PATCH: z.any().optional(),
257
- /** HEAD handler */
258
- HEAD: z.any().optional(),
259
- /** OPTIONS handler */
260
- OPTIONS: z.any().optional(),
261
- });
262
-
263
- // === TypeScript Type Definitions ===
264
-
265
- export type RouteType = z.infer<typeof RouteTypeSchema>;
266
- export type FileSystemRoute = z.infer<typeof FileSystemRouteSchema>;
267
- export type RoutePageModule = z.infer<typeof RoutePageModuleSchema>;
268
- export type RouteParams = z.infer<typeof RouteParamsSchema>;
269
- export type LoaderContext = z.infer<typeof LoaderContextSchema>;
270
- export type PageProps = z.infer<typeof PagePropsSchema>;
271
- export type Metadata = z.infer<typeof MetadataSchema>;
272
- export type ResolvedMetadata = z.infer<typeof ResolvedMetadataSchema>;
273
- export type MetadataChain = z.infer<typeof MetadataChainSchema>;
274
- export type RouteDiscoveryOptions = z.infer<typeof RouteDiscoveryOptionsSchema>;
275
- export type FileSystemRouterConfig = z.infer<typeof FileSystemRouterConfigSchema>;
276
- export type PageFile = z.infer<typeof PageFileSchema>;
277
- export type RouteHandler = z.infer<typeof RouteHandlerSchema>;
278
- export type RouteCacheEntry = z.infer<typeof RouteCacheEntrySchema>;
279
- export type FileSystemApiRoute = z.infer<typeof FileSystemApiRouteSchema>;
280
- export type FileSystemApiModule = z.infer<typeof FileSystemApiModuleSchema>;
281
-
282
- // === Function Type Definitions ===
283
-
284
- /**
285
- * Page Component Type
286
- */
287
- export type PageComponent<P extends PageProps = PageProps> = ComponentType<P>;
288
-
289
- /**
290
- * Metadata Generator Function Type
291
- */
292
- export type MetadataGenerator = (params: RouteParams) => Promise<Metadata>;
293
-
294
- /**
295
- * Page Loader Function Type
296
- */
297
- export type PageLoader = (context: LoaderContext) => Promise<unknown>;
298
-
299
- /**
300
- * Route Handler Function Type
301
- */
302
- export type RouteHandlerFunction = (request: Request, context: LoaderContext) => Promise<Response>;
303
-
304
- /**
305
- * File System API Handler Function Type
306
- */
307
- export type FileSystemApiHandler = (request: Request, context: LoaderContext) => Promise<Response>;
308
-
309
- // === Type Guards ===
310
-
311
- /**
312
- * Type guard for FileSystemRoute
313
- */
314
- export function isFileSystemRoute(data: unknown): data is FileSystemRoute {
315
- return FileSystemRouteSchema.safeParse(data).success;
316
- }
317
-
318
- /**
319
- * Type guard for RoutePageModule
320
- */
321
- export function isRoutePageModule(data: unknown): data is RoutePageModule {
322
- return RoutePageModuleSchema.safeParse(data).success;
323
- }
324
-
325
- /**
326
- * Type guard for Metadata
327
- */
328
- export function isMetadata(data: unknown): data is Metadata {
329
- return MetadataSchema.safeParse(data).success;
330
- }
331
-
332
- /**
333
- * Type guard for RouteParams
334
- */
335
- export function isRouteParams(data: unknown): data is RouteParams {
336
- return RouteParamsSchema.safeParse(data).success;
337
- }
338
-
339
- /**
340
- * Type guard for FileSystemApiModule
341
- */
342
- export function isFileSystemApiModule(data: unknown): data is FileSystemApiModule {
343
- return FileSystemApiModuleSchema.safeParse(data).success;
344
- }
345
-
346
- // === Re-exports from types/routing.ts (single source of truth) ===
347
-
348
- export type {
349
- ExtractRouteParams,
350
- ExtractOptionalParams,
351
- RouteParameters,
352
- TypedPageComponent,
353
- TypedPageComponentWithData,
354
- TypedMetadataGenerator,
355
- TypedPageLoader,
356
- TypedApiHandler,
357
- TypedApiModule,
358
- HasDynamicSegments,
359
- HasCatchAllSegments,
360
- HasOptionalSegments,
361
- CountDynamicSegments,
362
- ValidRoutePattern,
363
- ValidRouteExtension,
364
- PageComponentProps,
365
- } from '../types/routing.ts';
366
-
367
- export {
368
- isValidRouteParams,
369
- isValidPageProps,
370
- isValidRoutePattern,
371
- validatePageComponent,
372
- createTypedPageComponent,
373
- createTypedMetadataGenerator,
374
- createTypedPageLoader,
375
- createTypedApiHandler,
376
- } from '../types/routing.ts';
1
+ import { z } from 'zod';
2
+ import type { ComponentType } from 'preact/compat';
3
+
4
+ /**
5
+ * Route Type Schema - Defines the different types of routes supported
6
+ */
7
+ export const RouteTypeSchema = z.enum(['static', 'dynamic', 'catch-all', 'index', 'group']);
8
+
9
+ /**
10
+ * File System Route Schema - Represents a discovered route from the file system
11
+ */
12
+ export const FileSystemRouteSchema = z.object({
13
+ /** URL pattern for matching requests */
14
+ pattern: z.any(), // URLPattern object - can't validate with Zod
15
+ /** File path to the page component */
16
+ filePath: z.string().min(1),
17
+ /** Type of route (static, dynamic, etc.) */
18
+ routeType: RouteTypeSchema,
19
+ /** Dynamic segments extracted from the file path */
20
+ dynamicSegments: z.array(z.string()),
21
+ /** Route priority for conflict resolution (lower = higher priority) */
22
+ priority: z.number().int().min(0),
23
+ /** Whether this route is in a private folder */
24
+ isPrivate: z.boolean(),
25
+ /** Route group name if the route is in a group */
26
+ routeGroup: z.string().optional(),
27
+ });
28
+
29
+ /**
30
+ * Route Page Module Schema - Represents the exports from a page file in routing context
31
+ */
32
+ export const RoutePageModuleSchema = z.object({
33
+ /** Default export - the page component */
34
+ default: z.any(), // ComponentType<PageProps> - can't validate function types with Zod
35
+ /** Optional layout configuration for this page */
36
+ layoutConfig: z.any().optional(), // LayoutConfig from layout system
37
+ /** Optional metadata generator function */
38
+ generateMetadata: z.any().optional(), // (params: RouteParams) => Promise<Metadata>
39
+ /** Optional data loader function */
40
+ loader: z.any().optional(), // (context: LoaderContext) => Promise<any>
41
+ /** Optional frontmatter data from MDX files */
42
+ frontmatter: z.record(z.string(), z.any()).optional(), // Frontmatter metadata from MDX files
43
+ });
44
+
45
+ /**
46
+ * Route Parameters Schema - Parameters extracted from dynamic routes
47
+ */
48
+ export const RouteParamsSchema = z.record(z.string(), z.string());
49
+
50
+ /**
51
+ * Loader Context Schema - Context passed to page loaders
52
+ */
53
+ export const LoaderContextSchema = z.object({
54
+ /** HTTP request object */
55
+ request: z.instanceof(Request),
56
+ /** URL object for easy access */
57
+ url: z.instanceof(URL),
58
+ /** Route parameters */
59
+ params: RouteParamsSchema,
60
+ /** Query parameters */
61
+ query: z.instanceof(URLSearchParams),
62
+ /** State from middleware */
63
+ state: z.instanceof(Map),
64
+ });
65
+
66
+ /**
67
+ * Page Props Schema - Props passed to page components
68
+ */
69
+ export const PagePropsSchema = z.object({
70
+ /** Route parameters */
71
+ params: RouteParamsSchema,
72
+ /** Query parameters */
73
+ query: z.instanceof(URLSearchParams),
74
+ /** Data from loader function */
75
+ data: z.unknown().optional(),
76
+ });
77
+
78
+ /**
79
+ * Metadata Schema - SEO and meta information
80
+ */
81
+ export const MetadataSchema = z.object({
82
+ /** Page title */
83
+ title: z.string().optional(),
84
+ /** Page description */
85
+ description: z.string().optional(),
86
+ /** Keywords for SEO */
87
+ keywords: z.array(z.string()).optional(),
88
+ /** Open Graph data */
89
+ openGraph: z
90
+ .object({
91
+ title: z.string().optional(),
92
+ description: z.string().optional(),
93
+ image: z.url().optional(),
94
+ url: z.url().optional(),
95
+ type: z.string().optional(),
96
+ siteName: z.string().optional(),
97
+ })
98
+ .optional(),
99
+ /** Twitter Card data */
100
+ twitter: z
101
+ .object({
102
+ card: z.enum(['summary', 'summary_large_image', 'app', 'player']).optional(),
103
+ title: z.string().optional(),
104
+ description: z.string().optional(),
105
+ image: z.url().optional(),
106
+ site: z.string().optional(),
107
+ })
108
+ .optional(),
109
+ /** Schema.org structured data */
110
+ schema: z.array(z.record(z.string(), z.unknown())).optional(),
111
+ /** Canonical URL */
112
+ canonical: z.url().optional(),
113
+ /** Robots meta tag */
114
+ robots: z.string().optional(),
115
+ });
116
+
117
+ /**
118
+ * Resolved Metadata Schema - Final merged metadata for a route
119
+ */
120
+ export const ResolvedMetadataSchema = MetadataSchema.extend({
121
+ /** Source chain for debugging */
122
+ sources: z.array(z.string()).optional(),
123
+ /** Resolution timestamp */
124
+ resolvedAt: z.number().optional(),
125
+ });
126
+
127
+ /**
128
+ * Metadata Chain Schema - Hierarchical metadata from multiple sources
129
+ */
130
+ export const MetadataChainSchema = z.object({
131
+ /** Global metadata */
132
+ global: MetadataSchema.optional(),
133
+ /** Section-specific metadata */
134
+ sections: z.array(
135
+ z.object({
136
+ path: z.string(),
137
+ metadata: MetadataSchema,
138
+ })
139
+ ),
140
+ /** Page-specific metadata */
141
+ page: MetadataSchema.optional(),
142
+ });
143
+
144
+ /**
145
+ * Route Discovery Options Schema - Configuration for route discovery
146
+ */
147
+ export const RouteDiscoveryOptionsSchema = z.object({
148
+ /** Base directory to scan for pages */
149
+ pagesDirectory: z.string().min(1).default('src/pages'),
150
+ /** Base directory to scan for API routes */
151
+ apiDirectory: z.string().min(1).default('src/api'),
152
+ /** File extensions to include */
153
+ extensions: z.array(z.string()).default(['.tsx', '.ts', '.jsx', '.js']),
154
+ /** Directories to exclude from scanning */
155
+ excludeDirectories: z.array(z.string()).default(['node_modules', '.git']),
156
+ /** Enable file watching for development */
157
+ enableWatching: z.boolean().default(false),
158
+ /** Development mode features */
159
+ developmentMode: z.boolean().default(false),
160
+ /** Quiet mode - suppress verbose logging */
161
+ quietMode: z.boolean().default(false),
162
+ });
163
+
164
+ /**
165
+ * File System Router Configuration Schema
166
+ */
167
+ export const FileSystemRouterConfigSchema = z.object({
168
+ /** Route discovery options */
169
+ discovery: RouteDiscoveryOptionsSchema.optional(),
170
+ /** Enable file-system routing */
171
+ enabled: z.boolean().default(true),
172
+ /** Fallback to manual routes when file-system routes fail */
173
+ fallbackToManual: z.boolean().default(true),
174
+ /** Cache discovered routes */
175
+ enableCaching: z.boolean().default(true),
176
+ /** Cache TTL in milliseconds */
177
+ cacheTTL: z.number().positive().default(300000), // 5 minutes
178
+ });
179
+
180
+ /**
181
+ * Page File Schema - Information about a discovered page file
182
+ */
183
+ export const PageFileSchema = z.object({
184
+ /** Absolute file path */
185
+ filePath: z.string().min(1),
186
+ /** Relative path from pages directory */
187
+ relativePath: z.string().min(1),
188
+ /** File extension */
189
+ extension: z.string().min(1),
190
+ /** Whether file is in a private folder */
191
+ isPrivate: z.boolean(),
192
+ /** Route group if applicable */
193
+ routeGroup: z.string().optional(),
194
+ /** File modification time */
195
+ mtime: z.number().optional(),
196
+ });
197
+
198
+ /**
199
+ * Route Handler Schema - Complete route handler information
200
+ */
201
+ export const RouteHandlerSchema = z.object({
202
+ /** Route pattern */
203
+ pattern: z.any(), // URLPattern
204
+ /** Handler function */
205
+ handler: z.any(), // (request: Request, context: LoaderContext) => Promise<Response>
206
+ /** Route metadata */
207
+ metadata: z.object({
208
+ filePath: z.string(),
209
+ routeType: RouteTypeSchema,
210
+ priority: z.number(),
211
+ dynamicSegments: z.array(z.string()),
212
+ }),
213
+ });
214
+
215
+ /**
216
+ * Route Cache Entry Schema - Cached route information
217
+ */
218
+ export const RouteCacheEntrySchema = z.object({
219
+ /** Cached routes */
220
+ routes: z.array(FileSystemRouteSchema),
221
+ /** Cache timestamp */
222
+ timestamp: z.number(),
223
+ /** File modification times for cache invalidation */
224
+ fileMtimes: z.record(z.string(), z.number()),
225
+ });
226
+
227
+ /**
228
+ * File System API Route Schema - Represents an API endpoint route discovered from file system
229
+ */
230
+ export const FileSystemApiRouteSchema = z.object({
231
+ /** URL pattern for the API endpoint */
232
+ pattern: z.any(), // URLPattern
233
+ /** File path to the API handler */
234
+ filePath: z.string().min(1),
235
+ /** HTTP methods supported */
236
+ methods: z.array(z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'])),
237
+ /** Route priority */
238
+ priority: z.number().int().min(0),
239
+ /** Dynamic segments */
240
+ dynamicSegments: z.array(z.string()),
241
+ });
242
+
243
+ /**
244
+ * File System API Module Schema - Exports from an API route file
245
+ */
246
+ export const FileSystemApiModuleSchema = z.object({
247
+ /** GET handler */
248
+ GET: z.any().optional(), // (request: Request, context: any) => Promise<Response>
249
+ /** POST handler */
250
+ POST: z.any().optional(),
251
+ /** PUT handler */
252
+ PUT: z.any().optional(),
253
+ /** DELETE handler */
254
+ DELETE: z.any().optional(),
255
+ /** PATCH handler */
256
+ PATCH: z.any().optional(),
257
+ /** HEAD handler */
258
+ HEAD: z.any().optional(),
259
+ /** OPTIONS handler */
260
+ OPTIONS: z.any().optional(),
261
+ });
262
+
263
+ // === TypeScript Type Definitions ===
264
+
265
+ export type RouteType = z.infer<typeof RouteTypeSchema>;
266
+ export type FileSystemRoute = z.infer<typeof FileSystemRouteSchema>;
267
+ export type RoutePageModule = z.infer<typeof RoutePageModuleSchema>;
268
+ export type RouteParams = z.infer<typeof RouteParamsSchema>;
269
+ export type LoaderContext = z.infer<typeof LoaderContextSchema>;
270
+ export type PageProps = z.infer<typeof PagePropsSchema>;
271
+ export type Metadata = z.infer<typeof MetadataSchema>;
272
+ export type ResolvedMetadata = z.infer<typeof ResolvedMetadataSchema>;
273
+ export type MetadataChain = z.infer<typeof MetadataChainSchema>;
274
+ export type RouteDiscoveryOptions = z.infer<typeof RouteDiscoveryOptionsSchema>;
275
+ export type FileSystemRouterConfig = z.infer<typeof FileSystemRouterConfigSchema>;
276
+ export type PageFile = z.infer<typeof PageFileSchema>;
277
+ export type RouteHandler = z.infer<typeof RouteHandlerSchema>;
278
+ export type RouteCacheEntry = z.infer<typeof RouteCacheEntrySchema>;
279
+ export type FileSystemApiRoute = z.infer<typeof FileSystemApiRouteSchema>;
280
+ export type FileSystemApiModule = z.infer<typeof FileSystemApiModuleSchema>;
281
+
282
+ // === Function Type Definitions ===
283
+
284
+ /**
285
+ * Page Component Type
286
+ */
287
+ export type PageComponent<P extends PageProps = PageProps> = ComponentType<P>;
288
+
289
+ /**
290
+ * Metadata Generator Function Type
291
+ */
292
+ export type MetadataGenerator = (params: RouteParams) => Promise<Metadata>;
293
+
294
+ /**
295
+ * Page Loader Function Type
296
+ */
297
+ export type PageLoader = (context: LoaderContext) => Promise<unknown>;
298
+
299
+ /**
300
+ * Route Handler Function Type
301
+ */
302
+ export type RouteHandlerFunction = (request: Request, context: LoaderContext) => Promise<Response>;
303
+
304
+ /**
305
+ * File System API Handler Function Type
306
+ */
307
+ export type FileSystemApiHandler = (request: Request, context: LoaderContext) => Promise<Response>;
308
+
309
+ // === Type Guards ===
310
+
311
+ /**
312
+ * Type guard for FileSystemRoute
313
+ */
314
+ export function isFileSystemRoute(data: unknown): data is FileSystemRoute {
315
+ return FileSystemRouteSchema.safeParse(data).success;
316
+ }
317
+
318
+ /**
319
+ * Type guard for RoutePageModule
320
+ */
321
+ export function isRoutePageModule(data: unknown): data is RoutePageModule {
322
+ return RoutePageModuleSchema.safeParse(data).success;
323
+ }
324
+
325
+ /**
326
+ * Type guard for Metadata
327
+ */
328
+ export function isMetadata(data: unknown): data is Metadata {
329
+ return MetadataSchema.safeParse(data).success;
330
+ }
331
+
332
+ /**
333
+ * Type guard for RouteParams
334
+ */
335
+ export function isRouteParams(data: unknown): data is RouteParams {
336
+ return RouteParamsSchema.safeParse(data).success;
337
+ }
338
+
339
+ /**
340
+ * Type guard for FileSystemApiModule
341
+ */
342
+ export function isFileSystemApiModule(data: unknown): data is FileSystemApiModule {
343
+ return FileSystemApiModuleSchema.safeParse(data).success;
344
+ }
345
+
346
+ // === Re-exports from types/routing.ts (single source of truth) ===
347
+
348
+ export type {
349
+ ExtractRouteParams,
350
+ ExtractOptionalParams,
351
+ RouteParameters,
352
+ TypedPageComponent,
353
+ TypedPageComponentWithData,
354
+ TypedMetadataGenerator,
355
+ TypedPageLoader,
356
+ TypedApiHandler,
357
+ TypedApiModule,
358
+ HasDynamicSegments,
359
+ HasCatchAllSegments,
360
+ HasOptionalSegments,
361
+ CountDynamicSegments,
362
+ ValidRoutePattern,
363
+ ValidRouteExtension,
364
+ PageComponentProps,
365
+ } from '../types/routing.ts';
366
+
367
+ export {
368
+ isValidRouteParams,
369
+ isValidPageProps,
370
+ isValidRoutePattern,
371
+ validatePageComponent,
372
+ createTypedPageComponent,
373
+ createTypedMetadataGenerator,
374
+ createTypedPageLoader,
375
+ createTypedApiHandler,
376
+ } from '../types/routing.ts';