@vaadin/hilla-file-router 24.9.0-alpha6 → 24.9.0-beta2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/hilla-file-router",
3
- "version": "24.9.0-alpha6",
3
+ "version": "24.9.0-beta2",
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.9.0-alpha6",
66
- "@vaadin/hilla-react-auth": "24.9.0-alpha6",
67
- "@vaadin/hilla-react-signals": "24.9.0-alpha6",
65
+ "@vaadin/hilla-generator-utils": "24.9.0-beta2",
66
+ "@vaadin/hilla-react-auth": "24.9.0-beta2",
67
+ "@vaadin/hilla-react-signals": "24.9.0-beta2",
68
68
  "tsc-template": "0.2.3",
69
69
  "typescript": "5.8.3"
70
70
  }
@@ -64,6 +64,7 @@ export declare class RouterConfigurationBuilder {
64
64
  * @returns The current instance of the builder for method chaining.
65
65
  */
66
66
  withFallback(component: ComponentType, config?: ViewConfig): this;
67
+ withDeepWildcard(): this;
67
68
  /**
68
69
  * Adds the parent layout to all views with the `flowLayouts` flag set in the
69
70
  * ViewConfiguration.
@@ -77,6 +78,7 @@ export declare class RouterConfigurationBuilder {
77
78
  * @returns The current instance of the builder for method chaining.
78
79
  */
79
80
  withLayout(component: ComponentType): this;
81
+ withLayoutSkipping(): this;
80
82
  /**
81
83
  * Adds protection to the route, requiring authentication or authorization to
82
84
  * access it.
@@ -2,6 +2,7 @@ import { createBrowserRouter } from "react-router";
2
2
  import createFallbackTransformer, { createFallbackRoutes } from "./createFallbackTransformer.js";
3
3
  import createProtectTransformer from "./createProtectTransformer.js";
4
4
  import fileRouteTransformer from "./fileRouteTransformer.js";
5
+ import mergeDeepWildcard from "./mergeDeepWildcard.js";
5
6
  import mergeLayout from "./mergeLayout.js";
6
7
  import { mergeRouteTrees } from "./mergeRouteTrees.js";
7
8
  import mergeSkipLayouts from "./mergeSkipLayout.js";
@@ -88,6 +89,10 @@ export class RouterConfigurationBuilder {
88
89
  }
89
90
  return this;
90
91
  }
92
+ withDeepWildcard() {
93
+ this.#modifiers.push((originalRoutes) => mergeDeepWildcard(originalRoutes));
94
+ return this;
95
+ }
91
96
  /**
92
97
  * Adds the parent layout to all views with the `flowLayouts` flag set in the
93
98
  * ViewConfiguration.
@@ -107,6 +112,10 @@ export class RouterConfigurationBuilder {
107
112
  }
108
113
  return this;
109
114
  }
115
+ withLayoutSkipping() {
116
+ this.#modifiers.push((originalRoutes) => mergeSkipLayouts(originalRoutes));
117
+ return this;
118
+ }
110
119
  /**
111
120
  * Adds protection to the route, requiring authentication or authorization to
112
121
  * access it.
@@ -139,7 +148,7 @@ export class RouterConfigurationBuilder {
139
148
  * configured browser router
140
149
  */
141
150
  build(options) {
142
- this.#modifiers.push((originalRoutes) => mergeSkipLayouts(originalRoutes));
151
+ this.withLayoutSkipping();
143
152
  const routes = this.#modifiers.reduce((acc, mod) => mod(acc) ?? acc, undefined) ?? [];
144
153
  return {
145
154
  routes,
@@ -1 +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}
1
+ {"mappings":"AAEA,SAAS,yCAA4D;AAErE,OAAO,6BAA6B,4DAA6D;AACjG,OAAO,6DAA8D;AACrE,OAAO,qDAAsD;AAC7D,OAAO,+CAAgD;AACvD,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;CAED,mBAAyB;AACvB,OAAKL,WAAW,KAAK,CAAC,mBAAmB,kBAAkB,eAAe,CAAC;AAC3E,SAAO;CACR;;;;;;;;;;;;;CAcD,WAAWG,WAAgC;AACzC,OAAK,KAAKG,cAAc;AACtB,QAAKA,eAAe;AACpB,QAAKN,WAAW,KAAK,CAAC,mBAAmB,YAAY,gBAAgB,UAAU,CAAC;EACjF;AACD,SAAO;CACR;CAED,qBAA2B;AACzB,OAAKA,WAAW,KAAK,CAAC,mBAAmB,iBAAiB,eAAe,CAAC;AAC1E,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,OAAK,oBAAoB;EACzB,MAAM,SACJ,KAAKV,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 mergeDeepWildcard from './mergeDeepWildcard.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 withDeepWildcard(): this {\n this.#modifiers.push((originalRoutes) => mergeDeepWildcard(originalRoutes));\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 withLayoutSkipping(): this {\n this.#modifiers.push((originalRoutes) => mergeSkipLayouts(originalRoutes));\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.withLayoutSkipping();\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}
@@ -1,5 +1,5 @@
1
1
  import { createElement } from "react";
2
- import { getHandleFlag, RouteHandleFlag } from "./utils.js";
2
+ import { getHandleFlag, isIndexRoute, isOptionalRoute, isWildcardRoute, RouteHandleFlag } from "./utils.js";
3
3
  /**
4
4
  * Creates fallback routes for handling unmatched paths and index routes.
5
5
  *
@@ -20,30 +20,6 @@ export function createFallbackRoutes(component, config) {
20
20
  }];
21
21
  }
22
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
23
  * Creates a route transformer that adds fallback routes to handle unmatched
48
24
  * paths.
49
25
  *
@@ -1 +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}
1
+ {"mappings":"AAAA,SAA6B,4BAA6B;AAG1D,SACE,eACA,cACA,iBACA,iBACA,mCAEkB;;;;;;;;;AAmBpB,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;;;;;;;;;;;;;;;;;;;;;;;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","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 {\n getHandleFlag,\n isIndexRoute,\n isOptionalRoute,\n isWildcardRoute,\n RouteHandleFlag,\n type RouteTransformer,\n} 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 * 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,2 @@
1
+ import type { RouteObject } from "react-router";
2
+ export default function mergeDeepWildcard(originalRoutes: readonly RouteObject[] | undefined): readonly RouteObject[] | undefined;
@@ -0,0 +1,17 @@
1
+ import { transformTree } from "../../shared/transformTree.js";
2
+ import { isWildcardRoute } from "./utils.js";
3
+ export default function mergeDeepWildcard(originalRoutes) {
4
+ if (!originalRoutes) {
5
+ return originalRoutes;
6
+ }
7
+ return transformTree(originalRoutes, null, (routes, next) => routes.reduce((acc, route, _, arr) => {
8
+ const wildcard = arr.find(isWildcardRoute);
9
+ const children = route.children ? next(wildcard && route.children.every((r) => !isWildcardRoute(r)) ? [...route.children, wildcard] : route.children) : undefined;
10
+ acc.push({
11
+ ...route,
12
+ children
13
+ });
14
+ return acc;
15
+ }, []));
16
+ }
17
+ //# sourceMappingURL=./mergeDeepWildcard.js.map
@@ -0,0 +1 @@
1
+ {"mappings":"AACA,SAAS,oDAAqD;AAC9D,SAAS,mCAAoC;AAE7C,eAAe,SAAS,kBACtBA,gBACoC;AACpC,MAAK,gBAAgB;AACnB,SAAO;CACR;AAED,QAAO,cAA8D,gBAAgB,MAAM,CAAC,QAAQ,SAClG,OAAO,OAAsB,CAAC,KAAK,OAAO,GAAG,QAAQ;EACnD,MAAM,WAAW,IAAI,KAAK,gBAAgB;EAC1C,MAAM,WAAW,MAAM,WACnB,KACE,YAAY,MAAM,SAAS,MAAM,CAAC,OAAO,gBAAgB,EAAE,CAAC,GACxD,CAAC,GAAG,MAAM,UAAU,QAAS,IAC7B,MAAM,SACX,GACD;AAEJ,MAAI,KAAK;GACP,GAAG;GACH;EACD,EAAgB;AAEjB,SAAO;CACR,GAAE,CAAE,EAAC,CACP;AACF","names":["originalRoutes: readonly RouteObject[] | undefined"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/mergeDeepWildcard.ts"],"sourcesContent":["import type { RouteObject } from 'react-router';\nimport { transformTree } from '../../shared/transformTree.js';\nimport { isWildcardRoute } from './utils.js';\n\nexport default function mergeDeepWildcard(\n originalRoutes: readonly RouteObject[] | undefined,\n): readonly RouteObject[] | undefined {\n if (!originalRoutes) {\n return originalRoutes;\n }\n\n return transformTree<readonly RouteObject[], readonly RouteObject[]>(originalRoutes, null, (routes, next) =>\n routes.reduce<RouteObject[]>((acc, route, _, arr) => {\n const wildcard = arr.find(isWildcardRoute);\n const children = route.children\n ? next(\n wildcard && route.children.every((r) => !isWildcardRoute(r))\n ? [...route.children, wildcard]\n : route.children,\n )\n : undefined;\n\n acc.push({\n ...route,\n children,\n } as RouteObject);\n\n return acc;\n }, []),\n );\n}\n"],"version":3}
@@ -85,3 +85,21 @@ export type RouteHandleFlag = (typeof RouteHandleFlag)[keyof typeof RouteHandleF
85
85
  * @returns The value of the flag if it exists, otherwise undefined.
86
86
  */
87
87
  export declare function getHandleFlag<T extends RouteHandleFlag>(route: RouteObject, flag: T): boolean | undefined;
88
+ /**
89
+ * Determines whether the given route object represents an index route.
90
+ *
91
+ * @param route - The route object to check.
92
+ */
93
+ export declare function isIndexRoute(route: RouteObject): boolean;
94
+ /**
95
+ * Determines whether the given route is optional based on its path.
96
+ *
97
+ * @param route - The route object to check.
98
+ */
99
+ export declare function isOptionalRoute(route: RouteObject): boolean;
100
+ /**
101
+ * Determines whether the given route is a wildcard route.
102
+ *
103
+ * @param route - The route object to check.
104
+ */
105
+ export declare function isWildcardRoute(route: RouteObject): boolean;
@@ -52,4 +52,28 @@ export function getHandleFlag(route, flag) {
52
52
  }
53
53
  return undefined;
54
54
  }
55
+ /**
56
+ * Determines whether the given route object represents an index route.
57
+ *
58
+ * @param route - The route object to check.
59
+ */
60
+ export function isIndexRoute(route) {
61
+ return !!route.index;
62
+ }
63
+ /**
64
+ * Determines whether the given route is optional based on its path.
65
+ *
66
+ * @param route - The route object to check.
67
+ */
68
+ export function isOptionalRoute(route) {
69
+ return !!route.path?.includes("?");
70
+ }
71
+ /**
72
+ * Determines whether the given route is a wildcard route.
73
+ *
74
+ * @param route - The route object to check.
75
+ */
76
+ export function isWildcardRoute(route) {
77
+ return route.path === "*";
78
+ }
55
79
  //# sourceMappingURL=./utils.js.map
@@ -1 +1 @@
1
- {"mappings":";;;;;;AAsDA,OAAO,SAAS,mBAAmBA,QAAuC;AACxE,QACG,aAAa,iBAAiB,OAAO,YAAY,cACjD,YAAY,iBAAiB,OAAO,WAAW;AAEnD;;;;;;;AAQD,OAAO,SAAS,eAAoCC,OAAkB;AACpE,SAAQ,EAAE,MAAM,QAAQ,GAAG,GAAG,MAAM,WAAW,MAAM,IAAI;AAC1D;;;;;;;;;;;;;;;;;;;AAoBD,OAAO,MAAM,kBAAkB;CAC7B,aAAa;CACb,iBAAiB;CACjB,cAAc;AACf;;;;;;;;AAUD,OAAO,SAAS,cAAyCC,OAAoBC,MAA8B;AACzG,YAAW,MAAM,WAAW,YAAY,QAAQ,MAAM,QAAQ;AAC5D,SAAQ,MAAM,OAA8B;CAC7C;AAED,QAAO;AACR","names":["module: Module","route: T","route: RouteObject","flag: T"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/utils.ts"],"sourcesContent":["import type { RouteObject } from 'react-router';\nimport type { Module, RouteModule } from '../../types.js';\n\n/**\n * A function type that modifies the current route tree.\n *\n * @param routes - The current route tree to process.\n * @returns An optional readonly array of RouteObject instances after modification\n */\nexport type RouteTreeModifier = (routes: readonly RouteObject[] | undefined) => readonly RouteObject[] | undefined;\n\n/**\n * A route-like object that can be used in the route tree.\n */\nexport interface RouteLike {\n path?: string;\n children?: readonly this[];\n}\n\n/**\n * Options for transforming a route object within the route configuration builder.\n *\n * @typeParam T - The type of the override object.\n */\nexport type RouteTransformerOptions<T extends RouteLike> = Readonly<{\n /**\n * Array of child route objects. If omitted, the route is considered leaf.\n */\n children?: readonly RouteObject[];\n /**\n * The original route object to transform.\n */\n original?: RouteObject;\n /**\n * Override object to apply custom transformations.\n */\n override?: T;\n /**\n * Indicates whether the route is a duplicate. Used to handle cases where\n * multiple routes may share the same path.\n */\n dupe?: boolean;\n}>;\n\nexport type RouteTransformer<T extends RouteLike = RouteLike> = (\n opts: RouteTransformerOptions<T>,\n) => RouteObject | undefined;\n\n/**\n * Checks if the given module is a valid React route module.\n *\n * @param module - The JS module to check.\n * @returns True if the module is a valid React route module, false otherwise.\n */\nexport function isReactRouteModule(module: Module): module is RouteModule {\n return (\n ('default' in module && typeof module.default === 'function') ||\n ('config' in module && typeof module.config === 'object')\n );\n}\n\n/**\n * Creates a unique key for a route based on its path and children.\n *\n * @param route - The route object to create a key for.\n * @returns A unique key string for the route.\n */\nexport function createRouteKey<T extends RouteLike>(route: T): string {\n return `${route.path ?? ''}-${route.children ? 'n' : 'i'}`;\n}\n\n/**\n * A set of flags that can be used to control the behavior of routes in the\n * router configuration.\n *\n * @remarks\n * These flags work together to control route rendering behavior:\n *\n * **Layout Control:**\n * - `FLOW_LAYOUT: true` - Route renders with server-side layout (Flow\n * component)\n * - `FLOW_LAYOUT: false` - Route renders without server-side layout\n * (client-only)\n * - `SKIP_LAYOUTS: true` - Route bypasses ALL layouts (overrides FLOW_LAYOUT)\n *\n * **Fallback Control:**\n * - `IGNORE_FALLBACK: true` - Route ignores fallback components, used\n * internally by {@link mergeLayout} and {@link mergeSkipLayouts}\n */\nexport const RouteHandleFlag = {\n FLOW_LAYOUT: 'flowLayout',\n IGNORE_FALLBACK: 'ignoreFallback',\n SKIP_LAYOUTS: 'skipLayouts',\n} as const;\nexport type RouteHandleFlag = (typeof RouteHandleFlag)[keyof typeof RouteHandleFlag];\n\n/**\n * Retrieves a specific flag from the route's handle object.\n *\n * @param route - The route object to retrieve the flag from.\n * @param flag - The flag to retrieve.\n * @returns The value of the flag if it exists, otherwise undefined.\n */\nexport function getHandleFlag<T extends RouteHandleFlag>(route: RouteObject, flag: T): boolean | undefined {\n if (typeof route.handle === 'object' && flag in route.handle) {\n return (route.handle as Record<T, boolean>)[flag];\n }\n\n return undefined;\n}\n"],"version":3}
1
+ {"mappings":";;;;;;AAsDA,OAAO,SAAS,mBAAmBA,QAAuC;AACxE,QACG,aAAa,iBAAiB,OAAO,YAAY,cACjD,YAAY,iBAAiB,OAAO,WAAW;AAEnD;;;;;;;AAQD,OAAO,SAAS,eAAoCC,OAAkB;AACpE,SAAQ,EAAE,MAAM,QAAQ,GAAG,GAAG,MAAM,WAAW,MAAM,IAAI;AAC1D;;;;;;;;;;;;;;;;;;;AAoBD,OAAO,MAAM,kBAAkB;CAC7B,aAAa;CACb,iBAAiB;CACjB,cAAc;AACf;;;;;;;;AAUD,OAAO,SAAS,cAAyCC,OAAoBC,MAA8B;AACzG,YAAW,MAAM,WAAW,YAAY,QAAQ,MAAM,QAAQ;AAC5D,SAAQ,MAAM,OAA8B;CAC7C;AAED,QAAO;AACR;;;;;;AAOD,OAAO,SAAS,aAAaD,OAA6B;AACxD,UAAS,MAAM;AAChB;;;;;;AAOD,OAAO,SAAS,gBAAgBA,OAA6B;AAC3D,UAAS,MAAM,MAAM,SAAS,IAAI;AACnC;;;;;;AAOD,OAAO,SAAS,gBAAgBA,OAA6B;AAC3D,QAAO,MAAM,SAAS;AACvB","names":["module: Module","route: T","route: RouteObject","flag: T"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/configuration-builder/utils.ts"],"sourcesContent":["import type { RouteObject } from 'react-router';\nimport type { Module, RouteModule } from '../../types.js';\n\n/**\n * A function type that modifies the current route tree.\n *\n * @param routes - The current route tree to process.\n * @returns An optional readonly array of RouteObject instances after modification\n */\nexport type RouteTreeModifier = (routes: readonly RouteObject[] | undefined) => readonly RouteObject[] | undefined;\n\n/**\n * A route-like object that can be used in the route tree.\n */\nexport interface RouteLike {\n path?: string;\n children?: readonly this[];\n}\n\n/**\n * Options for transforming a route object within the route configuration builder.\n *\n * @typeParam T - The type of the override object.\n */\nexport type RouteTransformerOptions<T extends RouteLike> = Readonly<{\n /**\n * Array of child route objects. If omitted, the route is considered leaf.\n */\n children?: readonly RouteObject[];\n /**\n * The original route object to transform.\n */\n original?: RouteObject;\n /**\n * Override object to apply custom transformations.\n */\n override?: T;\n /**\n * Indicates whether the route is a duplicate. Used to handle cases where\n * multiple routes may share the same path.\n */\n dupe?: boolean;\n}>;\n\nexport type RouteTransformer<T extends RouteLike = RouteLike> = (\n opts: RouteTransformerOptions<T>,\n) => RouteObject | undefined;\n\n/**\n * Checks if the given module is a valid React route module.\n *\n * @param module - The JS module to check.\n * @returns True if the module is a valid React route module, false otherwise.\n */\nexport function isReactRouteModule(module: Module): module is RouteModule {\n return (\n ('default' in module && typeof module.default === 'function') ||\n ('config' in module && typeof module.config === 'object')\n );\n}\n\n/**\n * Creates a unique key for a route based on its path and children.\n *\n * @param route - The route object to create a key for.\n * @returns A unique key string for the route.\n */\nexport function createRouteKey<T extends RouteLike>(route: T): string {\n return `${route.path ?? ''}-${route.children ? 'n' : 'i'}`;\n}\n\n/**\n * A set of flags that can be used to control the behavior of routes in the\n * router configuration.\n *\n * @remarks\n * These flags work together to control route rendering behavior:\n *\n * **Layout Control:**\n * - `FLOW_LAYOUT: true` - Route renders with server-side layout (Flow\n * component)\n * - `FLOW_LAYOUT: false` - Route renders without server-side layout\n * (client-only)\n * - `SKIP_LAYOUTS: true` - Route bypasses ALL layouts (overrides FLOW_LAYOUT)\n *\n * **Fallback Control:**\n * - `IGNORE_FALLBACK: true` - Route ignores fallback components, used\n * internally by {@link mergeLayout} and {@link mergeSkipLayouts}\n */\nexport const RouteHandleFlag = {\n FLOW_LAYOUT: 'flowLayout',\n IGNORE_FALLBACK: 'ignoreFallback',\n SKIP_LAYOUTS: 'skipLayouts',\n} as const;\nexport type RouteHandleFlag = (typeof RouteHandleFlag)[keyof typeof RouteHandleFlag];\n\n/**\n * Retrieves a specific flag from the route's handle object.\n *\n * @param route - The route object to retrieve the flag from.\n * @param flag - The flag to retrieve.\n * @returns The value of the flag if it exists, otherwise undefined.\n */\nexport function getHandleFlag<T extends RouteHandleFlag>(route: RouteObject, flag: T): boolean | undefined {\n if (typeof route.handle === 'object' && flag in route.handle) {\n return (route.handle as Record<T, boolean>)[flag];\n }\n\n return undefined;\n}\n\n/**\n * Determines whether the given route object represents an index route.\n *\n * @param route - The route object to check.\n */\nexport function 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 */\nexport function 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 */\nexport function isWildcardRoute(route: RouteObject): boolean {\n return route.path === '*';\n}\n"],"version":3}
@@ -19,7 +19,7 @@ export function createMenuItems() {
19
19
  vaadinObj.registrations ??= [];
20
20
  vaadinObj.registrations.push({
21
21
  is: feature ? `@vaadin/hilla-file-router/${feature}` : "@vaadin/hilla-file-router",
22
- version: "24.9.0-alpha6"
22
+ version: "24.9.0-beta2"
23
23
  });
24
24
  })("createMenuItems", window.Vaadin);
25
25
  const collator = new Intl.Collator("en-US");
@@ -1 +1 @@
1
- {"mappings":"AACA,SAAsB,2CAA4C;AAIlE,OAAO,MAAMA,cAAkF,OAC5F,OAAwB,QAAQ,MAClC;AAED,SAAS,WAAWC,OAA4B;AAC9C,UAAS,MAAM,MAAM;AACtB;AAED,SAAS,uBAAuBC,MAAuB;AACrD,QAAO,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,QAAQ,WAAW,IAAI,CAAC;AAClE;;;;;;;;;AAUD,OAAO,SAAS,kBAA2D;AAGzE,EAAC,CAAC,SAAS,YAAa,WAAW,WAAW,CAAE,MAAM;AACtD,YAAU,kBAAkB,CAAE;AAC9B,YAAU,cAAc,KAAK;GAC3B,IAAI,WAAW,4BAA4B,QAAQ,IAAI;GACvD,SAAS;EACV,EAAC;CACH,GAAE,mBAAoB,OAAwB,OAAO;CACpD,MAAM,WAAW,IAAI,KAAK,SAAS;AACnC,MAAK,YAAY,OAAO;AACtB,SAAO,CAAE;CACV;CAED,MAAM,QAAQ,OAAO,QAAQ,YAAY,MAAM;AAE/C,QACE,MAEG,OAAO,CAAC,CAAC,MAAM,MAAM,MAAM,WAAW,MAAM,KAAK,uBAAuB,KAAK,CAAC,CAE9E,IAAI,CAAC,CAAC,MAAM,OAAO,MAAM;EACxB,IAAI;EACJ,MAAM,OAAO,MAAM;EACnB,OAAO,OAAO,MAAM,SAAS,OAAO;EACpC,OAAO,OAAO,MAAM;EACpB,QAAQ,OAAO;CAChB,GAAE,CAEF,KAAK,CAAC,OAAO,UAAU;EACtB,MAAM,cAAc,MAAM,SAAS,OAAO,cAAc,MAAM,SAAS,OAAO;AAC9E,SAAO,eAAe,IAAI,aAAa,SAAS,QAAQ,MAAM,IAAI,MAAM,GAAG;CAC5E,EAAC;AAEP;AAED,IAAI,OAAO,KAAK,KAAK;AACnB,QAAO,KAAK,IAAI,GAAG,mBAAmB,MAAM;AAC1C,QAAM,iBAAiB,CACpB,KAAK,OAAO,SAAS,KAAK,MAAM,CAAC,CACjC,KAAK,CAAC,SAAS;AACd,eAAY,QAAQ;EACrB,EAAC,CACD,MAAM,CAACC,MAAe;AACrB,WAAQ,MAAM,8BAA8B,EAAE;EAC/C,EAAC;CACL,EAAC;AACH","names":["viewsSignal: Signal<Readonly<Record<string, Readonly<ViewConfig>>> | undefined>","value: ViewConfig","path: string","e: unknown"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/createMenuItems.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\nimport { type Signal, signal } from '@vaadin/hilla-react-signals';\nimport type { VaadinWindow } from '../shared/internal.js';\nimport type { MenuItem, ViewConfig } from '../types.js';\n\nexport const viewsSignal: Signal<Readonly<Record<string, Readonly<ViewConfig>>> | undefined> = signal(\n (window as VaadinWindow).Vaadin?.views,\n);\n\nfunction isExcluded(value: ViewConfig): boolean {\n return !!value.menu?.exclude;\n}\n\nfunction hasVariablePathSegment(path: string): boolean {\n return path.split('/').some((segment) => segment.startsWith(':'));\n}\n\n/**\n * Creates menu items from the views provided by the server. The views are sorted according to the\n * {@link ViewConfig.menu.order}, filtered out if they are explicitly excluded via {@link ViewConfig.menu.exclude}.\n * Note that views with no order are put below views with an order. Ties are resolved based on the path string\n * comparison.\n *\n * @returns A list of menu items.\n */\nexport function createMenuItems<T = unknown>(): ReadonlyArray<MenuItem<T>> {\n // @ts-expect-error: esbuild injection\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n ((feature, vaadinObj = (globalThis.Vaadin ??= {})) => {\n vaadinObj.registrations ??= [];\n vaadinObj.registrations.push({\n is: feature ? `@vaadin/hilla-file-router/${feature}` : '@vaadin/hilla-file-router',\n version: '24.9.0-alpha6',\n });\n})('createMenuItems', (window as VaadinWindow).Vaadin);\n const collator = new Intl.Collator('en-US');\n if (!viewsSignal.value) {\n return [];\n }\n\n const views = Object.entries(viewsSignal.value);\n\n return (\n views\n // Filter out the views that are explicitly excluded from the menu.\n .filter(([path, value]) => !isExcluded(value) && !hasVariablePathSegment(path))\n // Map the views to menu items.\n .map(([path, config]) => ({\n to: path,\n icon: config.menu?.icon,\n title: config.menu?.title ?? config.title,\n order: config.menu?.order,\n detail: config.detail as T | undefined,\n }))\n // Sort views according to the order specified in the view configuration.\n .sort((menuA, menuB) => {\n const ordersDiff = (menuA.order ?? Number.MAX_VALUE) - (menuB.order ?? Number.MAX_VALUE);\n return ordersDiff !== 0 ? ordersDiff : collator.compare(menuA.to, menuB.to);\n })\n );\n}\n\nif (import.meta.hot) {\n import.meta.hot.on('fs-route-update', () => {\n fetch('?v-r=routeinfo')\n .then(async (resp) => resp.json())\n .then((json) => {\n viewsSignal.value = json;\n })\n .catch((e: unknown) => {\n console.error('Failed to fetch route info', e);\n });\n });\n}\n"],"version":3}
1
+ {"mappings":"AACA,SAAsB,2CAA4C;AAIlE,OAAO,MAAMA,cAAkF,OAC5F,OAAwB,QAAQ,MAClC;AAED,SAAS,WAAWC,OAA4B;AAC9C,UAAS,MAAM,MAAM;AACtB;AAED,SAAS,uBAAuBC,MAAuB;AACrD,QAAO,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,QAAQ,WAAW,IAAI,CAAC;AAClE;;;;;;;;;AAUD,OAAO,SAAS,kBAA2D;AAGzE,EAAC,CAAC,SAAS,YAAa,WAAW,WAAW,CAAE,MAAM;AACtD,YAAU,kBAAkB,CAAE;AAC9B,YAAU,cAAc,KAAK;GAC3B,IAAI,WAAW,4BAA4B,QAAQ,IAAI;GACvD,SAAS;EACV,EAAC;CACH,GAAE,mBAAoB,OAAwB,OAAO;CACpD,MAAM,WAAW,IAAI,KAAK,SAAS;AACnC,MAAK,YAAY,OAAO;AACtB,SAAO,CAAE;CACV;CAED,MAAM,QAAQ,OAAO,QAAQ,YAAY,MAAM;AAE/C,QACE,MAEG,OAAO,CAAC,CAAC,MAAM,MAAM,MAAM,WAAW,MAAM,KAAK,uBAAuB,KAAK,CAAC,CAE9E,IAAI,CAAC,CAAC,MAAM,OAAO,MAAM;EACxB,IAAI;EACJ,MAAM,OAAO,MAAM;EACnB,OAAO,OAAO,MAAM,SAAS,OAAO;EACpC,OAAO,OAAO,MAAM;EACpB,QAAQ,OAAO;CAChB,GAAE,CAEF,KAAK,CAAC,OAAO,UAAU;EACtB,MAAM,cAAc,MAAM,SAAS,OAAO,cAAc,MAAM,SAAS,OAAO;AAC9E,SAAO,eAAe,IAAI,aAAa,SAAS,QAAQ,MAAM,IAAI,MAAM,GAAG;CAC5E,EAAC;AAEP;AAED,IAAI,OAAO,KAAK,KAAK;AACnB,QAAO,KAAK,IAAI,GAAG,mBAAmB,MAAM;AAC1C,QAAM,iBAAiB,CACpB,KAAK,OAAO,SAAS,KAAK,MAAM,CAAC,CACjC,KAAK,CAAC,SAAS;AACd,eAAY,QAAQ;EACrB,EAAC,CACD,MAAM,CAACC,MAAe;AACrB,WAAQ,MAAM,8BAA8B,EAAE;EAC/C,EAAC;CACL,EAAC;AACH","names":["viewsSignal: Signal<Readonly<Record<string, Readonly<ViewConfig>>> | undefined>","value: ViewConfig","path: string","e: unknown"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/file-router/src/runtime/createMenuItems.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\nimport { type Signal, signal } from '@vaadin/hilla-react-signals';\nimport type { VaadinWindow } from '../shared/internal.js';\nimport type { MenuItem, ViewConfig } from '../types.js';\n\nexport const viewsSignal: Signal<Readonly<Record<string, Readonly<ViewConfig>>> | undefined> = signal(\n (window as VaadinWindow).Vaadin?.views,\n);\n\nfunction isExcluded(value: ViewConfig): boolean {\n return !!value.menu?.exclude;\n}\n\nfunction hasVariablePathSegment(path: string): boolean {\n return path.split('/').some((segment) => segment.startsWith(':'));\n}\n\n/**\n * Creates menu items from the views provided by the server. The views are sorted according to the\n * {@link ViewConfig.menu.order}, filtered out if they are explicitly excluded via {@link ViewConfig.menu.exclude}.\n * Note that views with no order are put below views with an order. Ties are resolved based on the path string\n * comparison.\n *\n * @returns A list of menu items.\n */\nexport function createMenuItems<T = unknown>(): ReadonlyArray<MenuItem<T>> {\n // @ts-expect-error: esbuild injection\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n ((feature, vaadinObj = (globalThis.Vaadin ??= {})) => {\n vaadinObj.registrations ??= [];\n vaadinObj.registrations.push({\n is: feature ? `@vaadin/hilla-file-router/${feature}` : '@vaadin/hilla-file-router',\n version: '24.9.0-beta2',\n });\n})('createMenuItems', (window as VaadinWindow).Vaadin);\n const collator = new Intl.Collator('en-US');\n if (!viewsSignal.value) {\n return [];\n }\n\n const views = Object.entries(viewsSignal.value);\n\n return (\n views\n // Filter out the views that are explicitly excluded from the menu.\n .filter(([path, value]) => !isExcluded(value) && !hasVariablePathSegment(path))\n // Map the views to menu items.\n .map(([path, config]) => ({\n to: path,\n icon: config.menu?.icon,\n title: config.menu?.title ?? config.title,\n order: config.menu?.order,\n detail: config.detail as T | undefined,\n }))\n // Sort views according to the order specified in the view configuration.\n .sort((menuA, menuB) => {\n const ordersDiff = (menuA.order ?? Number.MAX_VALUE) - (menuB.order ?? Number.MAX_VALUE);\n return ordersDiff !== 0 ? ordersDiff : collator.compare(menuA.to, menuB.to);\n })\n );\n}\n\nif (import.meta.hot) {\n import.meta.hot.on('fs-route-update', () => {\n fetch('?v-r=routeinfo')\n .then(async (resp) => resp.json())\n .then((json) => {\n viewsSignal.value = json;\n })\n .catch((e: unknown) => {\n console.error('Failed to fetch route info', e);\n });\n });\n}\n"],"version":3}