@vaadin/hilla-file-router 24.8.6 → 24.8.7

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 (38) hide show
  1. package/package.json +4 -4
  2. package/runtime/configuration-builder/RouterConfigurationBuilder.d.ts +129 -0
  3. package/runtime/configuration-builder/RouterConfigurationBuilder.js +153 -0
  4. package/runtime/configuration-builder/RouterConfigurationBuilder.js.map +1 -0
  5. package/runtime/configuration-builder/createFallbackTransformer.d.ts +44 -0
  6. package/runtime/configuration-builder/createFallbackTransformer.js +90 -0
  7. package/runtime/configuration-builder/createFallbackTransformer.js.map +1 -0
  8. package/runtime/configuration-builder/createProtectTransformer.d.ts +11 -0
  9. package/runtime/configuration-builder/createProtectTransformer.js +21 -0
  10. package/runtime/configuration-builder/createProtectTransformer.js.map +1 -0
  11. package/runtime/configuration-builder/fileRouteTransformer.d.ts +17 -0
  12. package/runtime/configuration-builder/fileRouteTransformer.js +47 -0
  13. package/runtime/configuration-builder/fileRouteTransformer.js.map +1 -0
  14. package/runtime/configuration-builder/mergeLayout.d.ts +24 -0
  15. package/runtime/configuration-builder/mergeLayout.js +71 -0
  16. package/runtime/configuration-builder/mergeLayout.js.map +1 -0
  17. package/runtime/configuration-builder/mergeRouteTrees.d.ts +24 -0
  18. package/runtime/configuration-builder/mergeRouteTrees.js +179 -0
  19. package/runtime/configuration-builder/mergeRouteTrees.js.map +1 -0
  20. package/runtime/configuration-builder/mergeSkipLayout.d.ts +18 -0
  21. package/runtime/configuration-builder/mergeSkipLayout.js +56 -0
  22. package/runtime/configuration-builder/mergeSkipLayout.js.map +1 -0
  23. package/runtime/configuration-builder/utils.d.ts +87 -0
  24. package/runtime/configuration-builder/utils.js +55 -0
  25. package/runtime/configuration-builder/utils.js.map +1 -0
  26. package/runtime/createMenuItems.js +1 -1
  27. package/runtime/createMenuItems.js.map +1 -1
  28. package/runtime.d.ts +1 -1
  29. package/runtime.js +1 -1
  30. package/runtime.js.map +1 -1
  31. package/shared/transformTree.d.ts +11 -1
  32. package/shared/transformTree.js.map +1 -1
  33. package/vite-plugin/collectRoutesFromFS.js +1 -1
  34. package/vite-plugin/collectRoutesFromFS.js.map +1 -1
  35. package/vite-plugin/createRoutesFromMeta.js.map +1 -1
  36. package/runtime/RouterConfigurationBuilder.d.ts +0 -76
  37. package/runtime/RouterConfigurationBuilder.js +0 -305
  38. package/runtime/RouterConfigurationBuilder.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/hilla-file-router",
3
- "version": "24.8.6",
3
+ "version": "24.8.7",
4
4
  "description": "Hilla file-based router",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -62,9 +62,9 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@ungap/with-resolvers": "0.1.0",
65
- "@vaadin/hilla-generator-utils": "24.8.6",
66
- "@vaadin/hilla-react-auth": "24.8.6",
67
- "@vaadin/hilla-react-signals": "24.8.6",
65
+ "@vaadin/hilla-generator-utils": "24.8.7",
66
+ "@vaadin/hilla-react-auth": "24.8.7",
67
+ "@vaadin/hilla-react-signals": "24.8.7",
68
68
  "tsc-template": "0.2.3",
69
69
  "typescript": "5.8.3"
70
70
  }
@@ -0,0 +1,129 @@
1
+ import type { ComponentType } from "react";
2
+ import { type RouteObject } from "react-router";
3
+ import type { AgnosticRoute, RouterBuildOptions, RouterConfiguration, ViewConfig } from "../../types.js";
4
+ import type { RouteLike, RouteTransformer } from "./utils.js";
5
+ /**
6
+ * A configuration builder for creating a Vaadin-specific router for React with
7
+ * authentication and server routes support.
8
+ *
9
+ * The configuration builder allows you to compose and modify route trees by
10
+ * chaining methods that add custom React routes, generated file-based routes,
11
+ * layout components, etc. Modifiers are accumulated and applied in order when
12
+ * building the final router configuration.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const { routes, router } = new RouteConfigurationBuilder()
17
+ * .withFileRoutes(fileRoutes)
18
+ * .withReactRoutes({ path: '/foo/baz', element: <FooBazPage /> })
19
+ * .withFallback(Flow)
20
+ * .protect('/login')
21
+ * .build();
22
+ * ```
23
+ */
24
+ export declare class RouterConfigurationBuilder {
25
+ #private;
26
+ /**
27
+ * Adds the given React routes to the current list of routes. All the routes
28
+ * are deeply merged to preserve the path uniqueness.
29
+ *
30
+ * @param routes - An array of React Router route objects to be merged into
31
+ * the current route list.
32
+ *
33
+ * @returns The current instance of the builder for method chaining.
34
+ */
35
+ withReactRoutes(routes: readonly RouteObject[]): this;
36
+ /**
37
+ * Adds the given file routes to the current list of routes. All the routes
38
+ * are transformed to React RouterObjects and deeply merged to preserve the
39
+ * path uniqueness.
40
+ *
41
+ * @param routes - An array of file-based route objects to be processed and
42
+ * merged into the current route list.
43
+ *
44
+ * @returns The current instance of the builder for method chaining.
45
+ */
46
+ withFileRoutes(routes: readonly AgnosticRoute[]): this;
47
+ /**
48
+ * Adds a fallback component for each branch of the current route tree.
49
+ *
50
+ * The fallback component is used when no other route matches the requested
51
+ * URL. In terms of Vaadin application, after no match on the client side, the
52
+ * turn goes to the server-side router.
53
+ *
54
+ * @remarks This method can be called only once. All the subsequent calls will
55
+ * be ignored.
56
+ *
57
+ * @remarks This method also runs the `withLayout` method with the given
58
+ * component to make sure server-side layout is applied to routes.
59
+ *
60
+ * @param component - The component to use as the fallback and layout
61
+ * component.
62
+ * @param config - Optional view configuration for the fallback component.
63
+ *
64
+ * @returns The current instance of the builder for method chaining.
65
+ */
66
+ withFallback(component: ComponentType, config?: ViewConfig): this;
67
+ /**
68
+ * Adds the parent layout to all views with the `flowLayouts` flag set in the
69
+ * ViewConfiguration.
70
+ *
71
+ * @remarks This method can be called only once. All the subsequent calls will
72
+ * be ignored.
73
+ *
74
+ * @param component - The component to use as the layout for the routes.
75
+ * Usually, it is `Flow` component.
76
+ *
77
+ * @returns The current instance of the builder for method chaining.
78
+ */
79
+ withLayout(component: ComponentType): this;
80
+ /**
81
+ * Adds protection to the route, requiring authentication or authorization to
82
+ * access it.
83
+ *
84
+ * @param redirectPath - Optional path to redirect to when protection fails.
85
+ * If not provided, the default redirect page (`/login`) will be used.
86
+ *
87
+ * @returns The current instance of the builder for method chaining.
88
+ */
89
+ protect(redirectPath?: string): this;
90
+ /**
91
+ * Deeply updates the current route tree, merging the existing routes with the
92
+ * given routes using the provided transformer callback.
93
+ *
94
+ * @param routes - The routes used to update the current route tree.
95
+ * @param callback - A transformer function that defines how the routes should
96
+ * be modified. Required if `routes` are not provided.
97
+ *
98
+ * @returns This RouteConfigurationBuilder instance for method chaining
99
+ */
100
+ update(routes: undefined, callback: RouteTransformer): this;
101
+ /**
102
+ * Deeply updates the current route tree, merging the existing routes with the
103
+ * given routes using the provided transformer callback.
104
+ *
105
+ * @typeParam T - The type of routes being updated.
106
+ *
107
+ * @param routes - The routes used to update the current route tree.
108
+ * @param callback - A transformer function that defines how the routes should
109
+ * be modified. Required if `routes` are not provided.
110
+ *
111
+ * @returns This RouteConfigurationBuilder instance for method chaining
112
+ */
113
+ update<T extends RouteLike>(routes: readonly T[], callback?: RouteTransformer<T>): this;
114
+ /**
115
+ * Builds the router configuration by applying all registered modifiers to the
116
+ * routes.
117
+ *
118
+ * @remarks
119
+ * This method applies the the logic for layout skipping along with any other
120
+ * registered modifiers to transform the routes.
121
+ *
122
+ * @param options - Optional React `createBrowserRouter` options to configure
123
+ * the router.
124
+ *
125
+ * @returns A RouterConfiguration object containing the processed routes and
126
+ * configured browser router
127
+ */
128
+ build(options?: RouterBuildOptions): RouterConfiguration;
129
+ }
@@ -0,0 +1,153 @@
1
+ import { createBrowserRouter } from "react-router";
2
+ import createFallbackTransformer, { createFallbackRoutes } from "./createFallbackTransformer.js";
3
+ import createProtectTransformer from "./createProtectTransformer.js";
4
+ import fileRouteTransformer from "./fileRouteTransformer.js";
5
+ import mergeLayout from "./mergeLayout.js";
6
+ import { mergeRouteTrees } from "./mergeRouteTrees.js";
7
+ import mergeSkipLayouts from "./mergeSkipLayout.js";
8
+ /**
9
+ * A configuration builder for creating a Vaadin-specific router for React with
10
+ * authentication and server routes support.
11
+ *
12
+ * The configuration builder allows you to compose and modify route trees by
13
+ * chaining methods that add custom React routes, generated file-based routes,
14
+ * layout components, etc. Modifiers are accumulated and applied in order when
15
+ * building the final router configuration.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const { routes, router } = new RouteConfigurationBuilder()
20
+ * .withFileRoutes(fileRoutes)
21
+ * .withReactRoutes({ path: '/foo/baz', element: <FooBazPage /> })
22
+ * .withFallback(Flow)
23
+ * .protect('/login')
24
+ * .build();
25
+ * ```
26
+ */
27
+ export class RouterConfigurationBuilder {
28
+ #modifiers = [];
29
+ #isFallbackSet = false;
30
+ #isLayoutSet = false;
31
+ /**
32
+ * Adds the given React routes to the current list of routes. All the routes
33
+ * are deeply merged to preserve the path uniqueness.
34
+ *
35
+ * @param routes - An array of React Router route objects to be merged into
36
+ * the current route list.
37
+ *
38
+ * @returns The current instance of the builder for method chaining.
39
+ */
40
+ withReactRoutes(routes) {
41
+ this.update(routes);
42
+ return this;
43
+ }
44
+ /**
45
+ * Adds the given file routes to the current list of routes. All the routes
46
+ * are transformed to React RouterObjects and deeply merged to preserve the
47
+ * path uniqueness.
48
+ *
49
+ * @param routes - An array of file-based route objects to be processed and
50
+ * merged into the current route list.
51
+ *
52
+ * @returns The current instance of the builder for method chaining.
53
+ */
54
+ withFileRoutes(routes) {
55
+ this.update(routes, fileRouteTransformer);
56
+ return this;
57
+ }
58
+ /**
59
+ * Adds a fallback component for each branch of the current route tree.
60
+ *
61
+ * The fallback component is used when no other route matches the requested
62
+ * URL. In terms of Vaadin application, after no match on the client side, the
63
+ * turn goes to the server-side router.
64
+ *
65
+ * @remarks This method can be called only once. All the subsequent calls will
66
+ * be ignored.
67
+ *
68
+ * @remarks This method also runs the `withLayout` method with the given
69
+ * component to make sure server-side layout is applied to routes.
70
+ *
71
+ * @param component - The component to use as the fallback and layout
72
+ * component.
73
+ * @param config - Optional view configuration for the fallback component.
74
+ *
75
+ * @returns The current instance of the builder for method chaining.
76
+ */
77
+ withFallback(component, config) {
78
+ if (!this.#isFallbackSet) {
79
+ this.#isFallbackSet = true;
80
+ this.withLayout(component);
81
+ const fallbackRoutes = createFallbackRoutes(component, config);
82
+ this.update(
83
+ // Add the fallback routes to the end of the route tree.
84
+ fallbackRoutes,
85
+ // Add the fallback routes to each route tree branch via transformer.
86
+ createFallbackTransformer(fallbackRoutes)
87
+ );
88
+ }
89
+ return this;
90
+ }
91
+ /**
92
+ * Adds the parent layout to all views with the `flowLayouts` flag set in the
93
+ * ViewConfiguration.
94
+ *
95
+ * @remarks This method can be called only once. All the subsequent calls will
96
+ * be ignored.
97
+ *
98
+ * @param component - The component to use as the layout for the routes.
99
+ * Usually, it is `Flow` component.
100
+ *
101
+ * @returns The current instance of the builder for method chaining.
102
+ */
103
+ withLayout(component) {
104
+ if (!this.#isLayoutSet) {
105
+ this.#isLayoutSet = true;
106
+ this.#modifiers.push((originalRoutes) => mergeLayout(originalRoutes, component));
107
+ }
108
+ return this;
109
+ }
110
+ /**
111
+ * Adds protection to the route, requiring authentication or authorization to
112
+ * access it.
113
+ *
114
+ * @param redirectPath - Optional path to redirect to when protection fails.
115
+ * If not provided, the default redirect page (`/login`) will be used.
116
+ *
117
+ * @returns The current instance of the builder for method chaining.
118
+ */
119
+ protect(redirectPath) {
120
+ this.update(undefined, createProtectTransformer(redirectPath));
121
+ return this;
122
+ }
123
+ update(routes, callback) {
124
+ this.#modifiers.push((originalRoutes) => mergeRouteTrees(originalRoutes, routes, callback));
125
+ return this;
126
+ }
127
+ /**
128
+ * Builds the router configuration by applying all registered modifiers to the
129
+ * routes.
130
+ *
131
+ * @remarks
132
+ * This method applies the the logic for layout skipping along with any other
133
+ * registered modifiers to transform the routes.
134
+ *
135
+ * @param options - Optional React `createBrowserRouter` options to configure
136
+ * the router.
137
+ *
138
+ * @returns A RouterConfiguration object containing the processed routes and
139
+ * configured browser router
140
+ */
141
+ build(options) {
142
+ this.#modifiers.push((originalRoutes) => mergeSkipLayouts(originalRoutes));
143
+ const routes = this.#modifiers.reduce((acc, mod) => mod(acc) ?? acc, undefined) ?? [];
144
+ return {
145
+ routes,
146
+ router: createBrowserRouter([...routes], {
147
+ basename: new URL(document.baseURI).pathname,
148
+ ...options
149
+ })
150
+ };
151
+ }
152
+ }
153
+ //# sourceMappingURL=./RouterConfigurationBuilder.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"AAEA,SAAS,yCAA4D;AAErE,OAAO,6BAA6B,4DAA6D;AACjG,OAAO,6DAA8D;AACrE,OAAO,qDAAsD;AAC7D,OAAO,mCAAoC;AAC3C,SAAS,6CAA8C;AACvD,OAAO,4CAA6C;;;;;;;;;;;;;;;;;;;;AAsBpD,OAAO,MAAM,2BAA2B;CACtC,AAASA,aAAkC,CAAE;CAC7C,iBAAiB;CACjB,eAAe;;;;;;;;;;CAWf,gBAAgBC,QAAsC;AACpD,OAAK,OAAO,OAAO;AACnB,SAAO;CACR;;;;;;;;;;;CAYD,eAAeC,QAAwC;AACrD,OAAK,OAAO,QAAQ,qBAAqB;AACzC,SAAO;CACR;;;;;;;;;;;;;;;;;;;;CAqBD,aAAaC,WAA0BC,QAA2B;AAChE,OAAK,KAAKC,gBAAgB;AACxB,QAAKA,iBAAiB;AACtB,QAAK,WAAW,UAAU;GAE1B,MAAM,iBAAiB,qBAAqB,WAAW,OAAO;AAE9D,QAAK;;IAEH;;IAEA,0BAA0B,eAAe;CAC1C;EACF;AACD,SAAO;CACR;;;;;;;;;;;;;CAcD,WAAWF,WAAgC;AACzC,OAAK,KAAKG,cAAc;AACtB,QAAKA,eAAe;AACpB,QAAKN,WAAW,KAAK,CAAC,mBAAmB,YAAY,gBAAgB,UAAU,CAAC;EACjF;AACD,SAAO;CACR;;;;;;;;;;CAWD,QAAQO,cAA6B;AACnC,OAAK,OAAO,WAAW,yBAAyB,aAAa,CAAC;AAC9D,SAAO;CACR;CA2BD,OAA4BC,QAAkCC,UAAqC;AACjG,OAAKT,WAAW,KAAK,CAAC,mBAAmB,gBAAgB,gBAAgB,QAAQ,SAAS,CAAC;AAC3F,SAAO;CACR;;;;;;;;;;;;;;;CAgBD,MAAMU,SAAmD;AACvD,OAAKV,WAAW,KAAK,CAAC,mBAAmB,iBAAiB,eAAe,CAAC;EAC1E,MAAM,SACJ,KAAKA,WAAW,OAA2C,CAAC,KAAK,QAAQ,IAAI,IAAI,IAAI,KAAK,UAAU,IAAI,CAAE;AAE5G,SAAO;GACL;GACA,QAAQ,oBAAoB,CAAC,GAAG,MAAO,GAAE;IAAE,UAAU,IAAI,IAAI,SAAS,SAAS;IAAU,GAAG;GAAS,EAAC;EACvG;CACF;AACF","names":["#modifiers","routes: readonly RouteObject[]","routes: readonly AgnosticRoute[]","component: ComponentType","config?: ViewConfig","#isFallbackSet","#isLayoutSet","redirectPath?: string","routes: readonly T[] | undefined","callback: RouteTransformer<T>","options?: RouterBuildOptions"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/RouterConfigurationBuilder.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\nimport type { ComponentType } from 'react';\nimport { createBrowserRouter, type RouteObject } from 'react-router';\nimport type { AgnosticRoute, RouterBuildOptions, RouterConfiguration, ViewConfig } from '../../types.js';\nimport createFallbackTransformer, { createFallbackRoutes } from './createFallbackTransformer.js';\nimport createProtectTransformer from './createProtectTransformer.js';\nimport fileRouteTransformer from './fileRouteTransformer.js';\nimport mergeLayout from './mergeLayout.js';\nimport { mergeRouteTrees } from './mergeRouteTrees.js';\nimport mergeSkipLayouts from './mergeSkipLayout.js';\nimport type { RouteLike, RouteTreeModifier, RouteTransformer } from './utils.js';\n\n/**\n * A configuration builder for creating a Vaadin-specific router for React with\n * authentication and server routes support.\n *\n * The configuration builder allows you to compose and modify route trees by\n * chaining methods that add custom React routes, generated file-based routes,\n * layout components, etc. Modifiers are accumulated and applied in order when\n * building the final router configuration.\n *\n * @example\n * ```typescript\n * const { routes, router } = new RouteConfigurationBuilder()\n * .withFileRoutes(fileRoutes)\n * .withReactRoutes({ path: '/foo/baz', element: <FooBazPage /> })\n * .withFallback(Flow)\n * .protect('/login')\n * .build();\n * ```\n */\nexport class RouterConfigurationBuilder {\n readonly #modifiers: RouteTreeModifier[] = [];\n #isFallbackSet = false;\n #isLayoutSet = false;\n\n /**\n * Adds the given React routes to the current list of routes. All the routes\n * are deeply merged to preserve the path uniqueness.\n *\n * @param routes - An array of React Router route objects to be merged into\n * the current route list.\n *\n * @returns The current instance of the builder for method chaining.\n */\n withReactRoutes(routes: readonly RouteObject[]): this {\n this.update(routes);\n return this;\n }\n\n /**\n * Adds the given file routes to the current list of routes. All the routes\n * are transformed to React RouterObjects and deeply merged to preserve the\n * path uniqueness.\n *\n * @param routes - An array of file-based route objects to be processed and\n * merged into the current route list.\n *\n * @returns The current instance of the builder for method chaining.\n */\n withFileRoutes(routes: readonly AgnosticRoute[]): this {\n this.update(routes, fileRouteTransformer);\n return this;\n }\n\n /**\n * Adds a fallback component for each branch of the current route tree.\n *\n * The fallback component is used when no other route matches the requested\n * URL. In terms of Vaadin application, after no match on the client side, the\n * turn goes to the server-side router.\n *\n * @remarks This method can be called only once. All the subsequent calls will\n * be ignored.\n *\n * @remarks This method also runs the `withLayout` method with the given\n * component to make sure server-side layout is applied to routes.\n *\n * @param component - The component to use as the fallback and layout\n * component.\n * @param config - Optional view configuration for the fallback component.\n *\n * @returns The current instance of the builder for method chaining.\n */\n withFallback(component: ComponentType, config?: ViewConfig): this {\n if (!this.#isFallbackSet) {\n this.#isFallbackSet = true;\n this.withLayout(component);\n\n const fallbackRoutes = createFallbackRoutes(component, config);\n\n this.update(\n // Add the fallback routes to the end of the route tree.\n fallbackRoutes,\n // Add the fallback routes to each route tree branch via transformer.\n createFallbackTransformer(fallbackRoutes),\n );\n }\n return this;\n }\n\n /**\n * Adds the parent layout to all views with the `flowLayouts` flag set in the\n * ViewConfiguration.\n *\n * @remarks This method can be called only once. All the subsequent calls will\n * be ignored.\n *\n * @param component - The component to use as the layout for the routes.\n * Usually, it is `Flow` component.\n *\n * @returns The current instance of the builder for method chaining.\n */\n withLayout(component: ComponentType): this {\n if (!this.#isLayoutSet) {\n this.#isLayoutSet = true;\n this.#modifiers.push((originalRoutes) => mergeLayout(originalRoutes, component));\n }\n return this;\n }\n\n /**\n * Adds protection to the route, requiring authentication or authorization to\n * access it.\n *\n * @param redirectPath - Optional path to redirect to when protection fails.\n * If not provided, the default redirect page (`/login`) will be used.\n *\n * @returns The current instance of the builder for method chaining.\n */\n protect(redirectPath?: string): this {\n this.update(undefined, createProtectTransformer(redirectPath));\n return this;\n }\n\n /**\n * Deeply updates the current route tree, merging the existing routes with the\n * given routes using the provided transformer callback.\n *\n * @param routes - The routes used to update the current route tree.\n * @param callback - A transformer function that defines how the routes should\n * be modified. Required if `routes` are not provided.\n *\n * @returns This RouteConfigurationBuilder instance for method chaining\n */\n update(routes: undefined, callback: RouteTransformer): this;\n\n /**\n * Deeply updates the current route tree, merging the existing routes with the\n * given routes using the provided transformer callback.\n *\n * @typeParam T - The type of routes being updated.\n *\n * @param routes - The routes used to update the current route tree.\n * @param callback - A transformer function that defines how the routes should\n * be modified. Required if `routes` are not provided.\n *\n * @returns This RouteConfigurationBuilder instance for method chaining\n */\n update<T extends RouteLike>(routes: readonly T[], callback?: RouteTransformer<T>): this;\n update<T extends RouteLike>(routes: readonly T[] | undefined, callback: RouteTransformer<T>): this {\n this.#modifiers.push((originalRoutes) => mergeRouteTrees(originalRoutes, routes, callback));\n return this;\n }\n\n /**\n * Builds the router configuration by applying all registered modifiers to the\n * routes.\n *\n * @remarks\n * This method applies the the logic for layout skipping along with any other\n * registered modifiers to transform the routes.\n *\n * @param options - Optional React `createBrowserRouter` options to configure\n * the router.\n *\n * @returns A RouterConfiguration object containing the processed routes and\n * configured browser router\n */\n build(options?: RouterBuildOptions): RouterConfiguration {\n this.#modifiers.push((originalRoutes) => mergeSkipLayouts(originalRoutes));\n const routes =\n this.#modifiers.reduce<readonly RouteObject[] | undefined>((acc, mod) => mod(acc) ?? acc, undefined) ?? [];\n\n return {\n routes,\n router: createBrowserRouter([...routes], { basename: new URL(document.baseURI).pathname, ...options }),\n };\n }\n}\n"],"version":3}
@@ -0,0 +1,44 @@
1
+ import { type ComponentType } from "react";
2
+ import type { RouteObject } from "react-router";
3
+ import type { ViewConfig } from "../../types.js";
4
+ import { type RouteTransformer } from "./utils.js";
5
+ /**
6
+ * A tuple of fallback routes:
7
+ * - A wildcard route (`path: '*'`) that renders the component for any unmatched
8
+ * path.
9
+ * - An index route (`index: true`) that renders the component for the empty
10
+ * path.
11
+ */
12
+ export type FallbackRoutes = readonly [notFoundFallback: RouteObject, indexFallback: RouteObject];
13
+ /**
14
+ * Creates fallback routes for handling unmatched paths and index routes.
15
+ *
16
+ * @param component - The React component to render for the fallback routes
17
+ * @param config - Optional view configuration to attach to the route handles
18
+ *
19
+ * @returns A tuple of fallback routes.
20
+ */
21
+ export declare function createFallbackRoutes(component: ComponentType, config?: ViewConfig): FallbackRoutes;
22
+ /**
23
+ * Creates a route transformer that adds fallback routes to handle unmatched
24
+ * paths.
25
+ *
26
+ * This transformer adds two types of fallback routes:
27
+ * - A wildcard route (`path: '*'`) that renders the specified fallback
28
+ * component for any unmatched path.
29
+ * - An index fallback route (`index: true`) that renders the fallback component
30
+ * for the empty path.
31
+ *
32
+ * The transformer logic determines which fallback to add based on the existing
33
+ * child routes:
34
+ * - If a wildcard child route already defined, only the index fallback is
35
+ * added.
36
+ * - If an index or optional child route exists, only the wildcard fallback is
37
+ * added.
38
+ * - Otherwise, both fallback routes are added.
39
+ *
40
+ * @param component - The React component to render as the fallback.
41
+ * @param config - A view configuration of the fallback route if any.
42
+ * @returns A route transformer function.
43
+ */
44
+ export default function createFallbackTransformer([notFoundFallback, indexFallback]: FallbackRoutes): RouteTransformer;
@@ -0,0 +1,90 @@
1
+ import { createElement } from "react";
2
+ import { getHandleFlag, RouteHandleFlag } from "./utils.js";
3
+ /**
4
+ * Creates fallback routes for handling unmatched paths and index routes.
5
+ *
6
+ * @param component - The React component to render for the fallback routes
7
+ * @param config - Optional view configuration to attach to the route handles
8
+ *
9
+ * @returns A tuple of fallback routes.
10
+ */
11
+ export function createFallbackRoutes(component, config) {
12
+ return [{
13
+ path: "*",
14
+ element: createElement(component),
15
+ handle: config
16
+ }, {
17
+ index: true,
18
+ element: createElement(component),
19
+ handle: config
20
+ }];
21
+ }
22
+ /**
23
+ * Determines whether the given route object represents an index route.
24
+ *
25
+ * @param route - The route object to check.
26
+ */
27
+ function isIndexRoute(route) {
28
+ return !!route.index;
29
+ }
30
+ /**
31
+ * Determines whether the given route is optional based on its path.
32
+ *
33
+ * @param route - The route object to check.
34
+ */
35
+ function isOptionalRoute(route) {
36
+ return !!route.path?.includes("?");
37
+ }
38
+ /**
39
+ * Determines whether the given route is a wildcard route.
40
+ *
41
+ * @param route - The route object to check.
42
+ */
43
+ function isWildcardRoute(route) {
44
+ return route.path === "*";
45
+ }
46
+ /**
47
+ * Creates a route transformer that adds fallback routes to handle unmatched
48
+ * paths.
49
+ *
50
+ * This transformer adds two types of fallback routes:
51
+ * - A wildcard route (`path: '*'`) that renders the specified fallback
52
+ * component for any unmatched path.
53
+ * - An index fallback route (`index: true`) that renders the fallback component
54
+ * for the empty path.
55
+ *
56
+ * The transformer logic determines which fallback to add based on the existing
57
+ * child routes:
58
+ * - If a wildcard child route already defined, only the index fallback is
59
+ * added.
60
+ * - If an index or optional child route exists, only the wildcard fallback is
61
+ * added.
62
+ * - Otherwise, both fallback routes are added.
63
+ *
64
+ * @param component - The React component to render as the fallback.
65
+ * @param config - A view configuration of the fallback route if any.
66
+ * @returns A route transformer function.
67
+ */
68
+ export default function createFallbackTransformer([notFoundFallback, indexFallback]) {
69
+ return ({ original, override, children, dupe }) => {
70
+ if (original && !getHandleFlag(original, RouteHandleFlag.IGNORE_FALLBACK) && !dupe) {
71
+ if (!children) {
72
+ return original;
73
+ }
74
+ let fallback;
75
+ if (children.some((route) => isWildcardRoute(route))) {
76
+ fallback = [indexFallback];
77
+ } else if (children.some((route) => isIndexRoute(route) || isOptionalRoute(route))) {
78
+ fallback = [notFoundFallback];
79
+ } else {
80
+ fallback = [notFoundFallback, indexFallback];
81
+ }
82
+ return {
83
+ ...original,
84
+ children: [...children, ...fallback]
85
+ };
86
+ }
87
+ return override;
88
+ };
89
+ }
90
+ //# sourceMappingURL=./createFallbackTransformer.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"AAAA,SAA6B,4BAA6B;AAG1D,SAAS,eAAe,mCAA2D;;;;;;;;;AAmBnF,OAAO,SAAS,qBAAqBA,WAA0BC,QAAqC;AAClG,QAAO,CACL;EAAE,MAAM;EAAK,SAAS,cAAc,UAAU;EAAE,QAAQ;CAAQ,GAChE;EAAE,OAAO;EAAM,SAAS,cAAc,UAAU;EAAE,QAAQ;CAAQ,CACnE;AACF;;;;;;AAOD,SAAS,aAAaC,OAA6B;AACjD,UAAS,MAAM;AAChB;;;;;;AAOD,SAAS,gBAAgBA,OAA6B;AACpD,UAAS,MAAM,MAAM,SAAS,IAAI;AACnC;;;;;;AAOD,SAAS,gBAAgBA,OAA6B;AACpD,QAAO,MAAM,SAAS;AACvB;;;;;;;;;;;;;;;;;;;;;;;AAwBD,eAAe,SAAS,0BAA0B,CAAC,kBAAkB,cAA8B,EAAoB;AACrH,QAAO,CAAC,EAAE,UAAU,UAAU,UAAU,MAAM,KAAK;AACjD,MAAI,aAAa,cAAc,UAAU,gBAAgB,gBAAgB,KAAK,MAAM;AAClF,QAAK,UAAU;AACb,WAAO;GACR;GAED,IAAIC;AAEJ,OAAI,SAAS,KAAK,CAAC,UAAU,gBAAgB,MAAM,CAAC,EAAE;AACpD,eAAW,CAAC,aAAc;GAC3B,WAAU,SAAS,KAAK,CAAC,UAAU,aAAa,MAAM,IAAI,gBAAgB,MAAM,CAAC,EAAE;AAClF,eAAW,CAAC,gBAAiB;GAC9B,OAAM;AACL,eAAW,CAAC,kBAAkB,aAAc;GAC7C;AAGD,UAAO;IACL,GAAG;IACH,UAAU,CAAC,GAAG,UAAU,GAAG,QAAS;GACrC;EACF;AAED,SAAO;CACR;AACF","names":["component: ComponentType","config?: ViewConfig","route: RouteObject","fallback: RouteObject[]"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/createFallbackTransformer.ts"],"sourcesContent":["import { type ComponentType, createElement } from 'react';\nimport type { RouteObject, NonIndexRouteObject } from 'react-router';\nimport type { ViewConfig } from '../../types.js';\nimport { getHandleFlag, RouteHandleFlag, type RouteTransformer } from './utils.js';\n\n/**\n * A tuple of fallback routes:\n * - A wildcard route (`path: '*'`) that renders the component for any unmatched\n * path.\n * - An index route (`index: true`) that renders the component for the empty\n * path.\n */\nexport type FallbackRoutes = readonly [notFoundFallback: RouteObject, indexFallback: RouteObject];\n\n/**\n * Creates fallback routes for handling unmatched paths and index routes.\n *\n * @param component - The React component to render for the fallback routes\n * @param config - Optional view configuration to attach to the route handles\n *\n * @returns A tuple of fallback routes.\n */\nexport function createFallbackRoutes(component: ComponentType, config?: ViewConfig): FallbackRoutes {\n return [\n { path: '*', element: createElement(component), handle: config },\n { index: true, element: createElement(component), handle: config },\n ];\n}\n\n/**\n * Determines whether the given route object represents an index route.\n *\n * @param route - The route object to check.\n */\nfunction isIndexRoute(route: RouteObject): boolean {\n return !!route.index;\n}\n\n/**\n * Determines whether the given route is optional based on its path.\n *\n * @param route - The route object to check.\n */\nfunction isOptionalRoute(route: RouteObject): boolean {\n return !!route.path?.includes('?');\n}\n\n/**\n * Determines whether the given route is a wildcard route.\n *\n * @param route - The route object to check.\n */\nfunction isWildcardRoute(route: RouteObject): boolean {\n return route.path === '*';\n}\n\n/**\n * Creates a route transformer that adds fallback routes to handle unmatched\n * paths.\n *\n * This transformer adds two types of fallback routes:\n * - A wildcard route (`path: '*'`) that renders the specified fallback\n * component for any unmatched path.\n * - An index fallback route (`index: true`) that renders the fallback component\n * for the empty path.\n *\n * The transformer logic determines which fallback to add based on the existing\n * child routes:\n * - If a wildcard child route already defined, only the index fallback is\n * added.\n * - If an index or optional child route exists, only the wildcard fallback is\n * added.\n * - Otherwise, both fallback routes are added.\n *\n * @param component - The React component to render as the fallback.\n * @param config - A view configuration of the fallback route if any.\n * @returns A route transformer function.\n */\nexport default function createFallbackTransformer([notFoundFallback, indexFallback]: FallbackRoutes): RouteTransformer {\n return ({ original, override, children, dupe }) => {\n if (original && !getHandleFlag(original, RouteHandleFlag.IGNORE_FALLBACK) && !dupe) {\n if (!children) {\n return original; //: IndexRouteObject;\n }\n\n let fallback: RouteObject[];\n\n if (children.some((route) => isWildcardRoute(route))) {\n fallback = [indexFallback];\n } else if (children.some((route) => isIndexRoute(route) || isOptionalRoute(route))) {\n fallback = [notFoundFallback];\n } else {\n fallback = [notFoundFallback, indexFallback];\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return {\n ...original,\n children: [...children, ...fallback],\n } as NonIndexRouteObject;\n }\n\n return override as RouteObject | undefined;\n };\n}\n"],"version":3}
@@ -0,0 +1,11 @@
1
+ import type { RouteTransformer } from "./utils.js";
2
+ /**
3
+ * Creates a route transformer that applies route protection to a given route,
4
+ * optionally redirecting unauthorized access to a specified path.
5
+ *
6
+ * @param redirectPath - Optional path to redirect unauthorized users to.
7
+ * Defaults to '/login'.
8
+ *
9
+ * @returns A route transformer function that applies protection to the route.
10
+ */
11
+ export default function createProtectTransformer(redirectPath?: string): RouteTransformer;
@@ -0,0 +1,21 @@
1
+ import { protectRoute } from "@vaadin/hilla-react-auth";
2
+ /**
3
+ * Creates a route transformer that applies route protection to a given route,
4
+ * optionally redirecting unauthorized access to a specified path.
5
+ *
6
+ * @param redirectPath - Optional path to redirect unauthorized users to.
7
+ * Defaults to '/login'.
8
+ *
9
+ * @returns A route transformer function that applies protection to the route.
10
+ */
11
+ export default function createProtectTransformer(redirectPath) {
12
+ return ({ original, children }) => {
13
+ if (!original) {
14
+ return original;
15
+ }
16
+ const finalRoute = protectRoute(original, redirectPath);
17
+ finalRoute.children = children;
18
+ return finalRoute;
19
+ };
20
+ }
21
+ //# sourceMappingURL=./createProtectTransformer.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"AAAA,SAAS,8CAA+C;;;;;;;;;;AAaxD,eAAe,SAAS,yBAAyBA,cAAyC;AACxF,QAAO,CAAC,EAAE,UAAU,UAAU,KAAK;AACjC,OAAK,UAAU;AACb,UAAO;EACR;EAED,MAAM,aAAa,aAAa,UAAU,aAAa;AACvD,aAAW,WAAW;AACtB,SAAO;CACR;AACF","names":["redirectPath?: string"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/createProtectTransformer.ts"],"sourcesContent":["import { protectRoute } from '@vaadin/hilla-react-auth';\nimport type { RouteObject } from 'react-router';\nimport type { RouteTransformer } from './utils.js';\n\n/**\n * Creates a route transformer that applies route protection to a given route,\n * optionally redirecting unauthorized access to a specified path.\n *\n * @param redirectPath - Optional path to redirect unauthorized users to.\n * Defaults to '/login'.\n *\n * @returns A route transformer function that applies protection to the route.\n */\nexport default function createProtectTransformer(redirectPath?: string): RouteTransformer {\n return ({ original, children }) => {\n if (!original) {\n return original;\n }\n\n const finalRoute = protectRoute(original, redirectPath);\n finalRoute.children = children as RouteObject[] | undefined;\n return finalRoute;\n };\n}\n"],"version":3}
@@ -0,0 +1,17 @@
1
+ import type { RouteObject } from "react-router";
2
+ import type { AgnosticRoute } from "../../types.js";
3
+ import { type RouteTransformerOptions } from "./utils.js";
4
+ /**
5
+ * Transforms a framework-agnostic route into a route object compatible with
6
+ * React Router and merges it with the existing route object if any.
7
+ *
8
+ * @param options - The route transformer options containing the existing route,
9
+ * any overrides, and child routes.
10
+ *
11
+ * @returns A `RouteObject` representing the transformed route, or the original
12
+ * route if no override is provided.
13
+ *
14
+ * @throws If the provided module does not export a React component by default
15
+ * nor a ViewConfig object as "config".
16
+ */
17
+ export default function fileRouteTransformer({ original, override, children }: RouteTransformerOptions<AgnosticRoute>): RouteObject | undefined;
@@ -0,0 +1,47 @@
1
+ import { createElement } from "react";
2
+ import { convertComponentNameToTitle } from "../../shared/convertComponentNameToTitle.js";
3
+ import { isReactRouteModule } from "./utils.js";
4
+ /**
5
+ * Transforms a framework-agnostic route into a route object compatible with
6
+ * React Router and merges it with the existing route object if any.
7
+ *
8
+ * @param options - The route transformer options containing the existing route,
9
+ * any overrides, and child routes.
10
+ *
11
+ * @returns A `RouteObject` representing the transformed route, or the original
12
+ * route if no override is provided.
13
+ *
14
+ * @throws If the provided module does not export a React component by default
15
+ * nor a ViewConfig object as "config".
16
+ */
17
+ export default function fileRouteTransformer({ original, override, children }) {
18
+ if (!override) {
19
+ return original;
20
+ }
21
+ const { module, component = module?.default, config = module?.config, path, flowLayout } = override;
22
+ if (module && !isReactRouteModule(module)) {
23
+ throw new Error(`The module for the "${path}" section doesn't have the React component exported by default or a ViewConfig object exported as "config"`);
24
+ }
25
+ const element = component ? createElement(component) : undefined;
26
+ const handle = {
27
+ ...config,
28
+ title: config?.title ?? convertComponentNameToTitle(component),
29
+ flowLayout: config?.flowLayout ?? flowLayout
30
+ };
31
+ if (path === "" && !children) {
32
+ return {
33
+ ...original,
34
+ element,
35
+ handle,
36
+ index: true
37
+ };
38
+ }
39
+ return {
40
+ ...original,
41
+ path: config?.route ?? path,
42
+ element,
43
+ children,
44
+ handle
45
+ };
46
+ }
47
+ //# sourceMappingURL=./fileRouteTransformer.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"AAAA,SAAS,4BAA6B;AAEtC,SAAS,gFAAiF;AAE1F,SAAS,sCAAqE;;;;;;;;;;;;;;AAe9E,eAAe,SAAS,qBAAqB,EAC3C,UACA,UACA,UACuC,EAA2B;AAClE,MAAK,UAAU;AACb,SAAO;CACR;CAED,MAAM,EAAE,QAAQ,YAAY,QAAQ,SAAS,SAAS,QAAQ,QAAQ,MAAM,YAAY,GAAG;AAE3F,KAAI,WAAW,mBAAmB,OAAO,EAAE;AACzC,QAAM,IAAI,OACP,sBAAsB,KAAK;CAE/B;CAED,MAAM,UAAU,YAAY,cAAc,UAAU,GAAG;CACvD,MAAM,SAAS;EACb,GAAG;EACH,OAAO,QAAQ,SAAS,4BAA4B,UAAU;EAC9D,YAAY,QAAQ,cAAc;CACnC;AAED,KAAI,SAAS,OAAO,UAAU;AAC5B,SAAO;GACL,GAAI;GACJ;GACA;GACA,OAAO;EACR;CACF;AAED,QAAO;EACL,GAAI;EACJ,MAAM,QAAQ,SAAS;EACvB;EACU;EACV;CACD;AACF","names":[],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/fileRouteTransformer.ts"],"sourcesContent":["import { createElement } from 'react';\nimport type { IndexRouteObject, NonIndexRouteObject, RouteObject } from 'react-router';\nimport { convertComponentNameToTitle } from '../../shared/convertComponentNameToTitle.js';\nimport type { AgnosticRoute } from '../../types.js';\nimport { isReactRouteModule, type RouteTransformerOptions } from './utils.js';\n\n/**\n * Transforms a framework-agnostic route into a route object compatible with\n * React Router and merges it with the existing route object if any.\n *\n * @param options - The route transformer options containing the existing route,\n * any overrides, and child routes.\n *\n * @returns A `RouteObject` representing the transformed route, or the original\n * route if no override is provided.\n *\n * @throws If the provided module does not export a React component by default\n * nor a ViewConfig object as \"config\".\n */\nexport default function fileRouteTransformer({\n original,\n override,\n children,\n}: RouteTransformerOptions<AgnosticRoute>): RouteObject | undefined {\n if (!override) {\n return original;\n }\n\n const { module, component = module?.default, config = module?.config, path, flowLayout } = override;\n\n if (module && !isReactRouteModule(module)) {\n throw new Error(\n `The module for the \"${path}\" section doesn't have the React component exported by default or a ViewConfig object exported as \"config\"`,\n );\n }\n\n const element = component ? createElement(component) : undefined;\n const handle = {\n ...config,\n title: config?.title ?? convertComponentNameToTitle(component),\n flowLayout: config?.flowLayout ?? flowLayout,\n };\n\n if (path === '' && !children) {\n return {\n ...(original as IndexRouteObject),\n element,\n handle,\n index: true,\n } satisfies IndexRouteObject;\n }\n\n return {\n ...(original as NonIndexRouteObject),\n path: config?.route ?? path,\n element,\n children: children as RouteObject[] | undefined,\n handle,\n } satisfies NonIndexRouteObject;\n}\n"],"version":3}
@@ -0,0 +1,24 @@
1
+ import { type ComponentType } from "react";
2
+ import type { RouteObject } from "react-router";
3
+ /**
4
+ * Splits out the server-side route tree based on the {@link ViewConfiguration.flowLayout}
5
+ * flag, and wraps them in the provided server layout component.
6
+ *
7
+ * @remarks
8
+ * Internally, routes are categorized into three groups:
9
+ * - **Server routes**: Routes with `flowLayout` flag explicitly set to `true`,
10
+ * or routes whose children have the flag enabled.
11
+ * - **Client routes**: Routes with `flowLayout` flag explicitly set to `false`,
12
+ * or routes with client-side children.
13
+ * - **Unknown routes**: Routes without explicit flags that inherit behavior
14
+ * from their parent context.
15
+ *
16
+ * Server routes get the {@link RouteHandleFlag.IGNORE_FALLBACK} flag set to
17
+ * prevent fallback route interference. Client routes are preserved as-is.
18
+ *
19
+ * @param originalRoutes - The current route tree to process.
20
+ * @param component - The layout component to wrap around server routes.
21
+ *
22
+ * @returns A new route configuration with the layout applied to server routes.
23
+ */
24
+ export default function mergeLayout(originalRoutes: readonly RouteObject[] | undefined, component: ComponentType): readonly RouteObject[] | undefined;