@analogjs/router 0.1.0-alpha.0 → 0.1.0-alpha.10

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/README.md CHANGED
@@ -40,14 +40,45 @@ bootstrapApplication(AppComponent, {
40
40
 
41
41
  This registers the Angular Router, along with the routes generated from the file structure.
42
42
 
43
+ Next, update the `tsconfig.app.json` to include the dynamically generated routes.
44
+
45
+ ```json
46
+ {
47
+ "extends": "./tsconfig.json",
48
+ "compilerOptions": {
49
+ "outDir": "../../dist/out-tsc",
50
+ "types": []
51
+ },
52
+ "files": ["src/main.ts", "src/polyfills.ts"],
53
+ "include": ["src/**/*.d.ts", "src/app/routes/**/*.ts"],
54
+ "exclude": ["**/*.test.ts", "**/*.spec.ts"]
55
+ }
56
+ ```
57
+
58
+ Last, add the router outlet to the root component.
59
+
60
+ ```ts
61
+ import { Component } from '@angular/core';
62
+ import { RouterOutlet } from '@angular/router';
63
+
64
+ @Component({
65
+ selector: 'app-root',
66
+ standalone: true,
67
+ imports: [RouterOutlet],
68
+ template: ` <router-outlet></router-outlet> `,
69
+ })
70
+ export class AppComponent {}
71
+ ```
72
+
43
73
  ## Defining Routes
44
74
 
45
75
  Routes are defined using folders and files in the `src/app/routes` folder.
46
76
 
47
77
  > Route components **must** be defined as the default export.
48
78
 
49
- There are 4 primary types of routes:
79
+ There are 5 primary types of routes:
50
80
 
81
+ - [Index Routes](#index-routes)
51
82
  - [Static Routes](#static-routes)
52
83
  - [Dynamic Routes](#dynamic-routes)
53
84
  - [Nested Routes](#nested-routes)
@@ -55,6 +86,23 @@ There are 4 primary types of routes:
55
86
 
56
87
  These routes can be combined in different ways to build to URLs for navigation.
57
88
 
89
+ ### Index Routes
90
+
91
+ Index routes are defined by using the filename as the route path enclosed in parenthesis.
92
+
93
+ The example route below in `src/app/routes/(home).ts` defines an `/` route.
94
+
95
+ ```ts
96
+ import { Component } from '@angular/core';
97
+
98
+ @Component({
99
+ selector: 'app-home',
100
+ standalone: true,
101
+ template: ` <h2>Welcome</h2> `,
102
+ })
103
+ export default class HomePageComponent {}
104
+ ```
105
+
58
106
  ### Static Routes
59
107
 
60
108
  Static routes are defined by using the filename as the route path.
@@ -82,7 +130,7 @@ Dynamic routes are defined by using the filename as the route path enclosed in s
82
130
 
83
131
  The parameter for the route is extracted from the route path.
84
132
 
85
- The example route below in `src/app/routes/produtcs.[productId].ts` defines a `/products/:productId` route.
133
+ The example route below in `src/app/routes/products.[productId].ts` defines a `/products/:productId` route.
86
134
 
87
135
  ```ts
88
136
  import { Component } from '@angular/core';
@@ -121,7 +169,7 @@ src/
121
169
  └── routes/
122
170
  │ └── products/
123
171
  │ ├──[productId].ts
124
- │ └──index.ts
172
+ │ └──(products-list).ts
125
173
  └── products.ts
126
174
  ```
127
175
 
@@ -149,7 +197,7 @@ import { RouterOutlet } from '@angular/router';
149
197
  export default class ProductsComponent {}
150
198
  ```
151
199
 
152
- The nested `src/app/routes/products/index.ts` file contains the `/products` list page.
200
+ The nested `src/app/routes/products/(products-list).ts` file contains the `/products` list page.
153
201
 
154
202
  ```ts
155
203
  import { Component } from '@angular/core';
@@ -216,19 +264,19 @@ export default class PageNotFoundComponent {}
216
264
 
217
265
  ## Route Metadata
218
266
 
219
- Additional metadata to add to the generated route config for each route can be done using the `defineRouteMeta` function. This is where you can define the page title, any necessary guards, resolvers, providers, and more.
267
+ Additional metadata to add to the generated route config for each route can be done using the `RouteMeta` type. This is where you can define the page title, any necessary guards, resolvers, providers, and more.
220
268
 
221
269
  ```ts
222
270
  import { Component } from '@angular/core';
223
- import { defineRouteMeta } from '@analogjs/router';
271
+ import { RouteMeta } from '@analogjs/router';
224
272
 
225
273
  import { AboutService } from './about.service';
226
274
 
227
- export const routeMeta = defineRouteMeta({
275
+ export const routeMeta: RouteMeta = {
228
276
  title: 'About Analog',
229
277
  canActivate: [() => true],
230
278
  providers: [AboutService],
231
- });
279
+ };
232
280
 
233
281
  @Component({
234
282
  selector: 'app-about',
package/esm2020/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  export { routes } from './lib/routes';
2
2
  export { defineRouteMeta, injectActivatedRoute, injectRouter, } from './lib/define-route';
3
- export { provideFileRouter } from './lib/provide-file-routes';
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9yb3V0ZXIvc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUNMLGVBQWUsRUFDZixvQkFBb0IsRUFDcEIsWUFBWSxHQUNiLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkJBQTJCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyByb3V0ZXMgfSBmcm9tICcuL2xpYi9yb3V0ZXMnO1xuZXhwb3J0IHtcbiAgZGVmaW5lUm91dGVNZXRhLFxuICBpbmplY3RBY3RpdmF0ZWRSb3V0ZSxcbiAgaW5qZWN0Um91dGVyLFxufSBmcm9tICcuL2xpYi9kZWZpbmUtcm91dGUnO1xuZXhwb3J0IHsgcHJvdmlkZUZpbGVSb3V0ZXIgfSBmcm9tICcuL2xpYi9wcm92aWRlLWZpbGUtcm91dGVzJztcbiJdfQ==
3
+ export { provideFileRouter } from './lib/provide-file-router';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9yb3V0ZXIvc3JjL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUNMLGVBQWUsRUFDZixvQkFBb0IsRUFDcEIsWUFBWSxHQUNiLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMkJBQTJCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyByb3V0ZXMgfSBmcm9tICcuL2xpYi9yb3V0ZXMnO1xuZXhwb3J0IHtcbiAgZGVmaW5lUm91dGVNZXRhLFxuICBpbmplY3RBY3RpdmF0ZWRSb3V0ZSxcbiAgaW5qZWN0Um91dGVyLFxufSBmcm9tICcuL2xpYi9kZWZpbmUtcm91dGUnO1xuZXhwb3J0IHsgUm91dGVNZXRhIH0gZnJvbSAnLi9saWIvbW9kZWxzJztcbmV4cG9ydCB7IHByb3ZpZGVGaWxlUm91dGVyIH0gZnJvbSAnLi9saWIvcHJvdmlkZS1maWxlLXJvdXRlcic7XG5leHBvcnQgeyBNZXRhVGFnIH0gZnJvbSAnLi9saWIvbWV0YS10YWdzJztcbiJdfQ==
@@ -2,6 +2,9 @@ import { inject } from '@angular/core';
2
2
  import { Router } from '@angular/router';
3
3
  import { ActivatedRoute } from '@angular/router';
4
4
  /**
5
+ * @deprecated Use `RouteMeta` type instead.
6
+ * For more info see: https://github.com/analogjs/analog/issues/223
7
+ *
5
8
  * Defines additional route config metadata. This
6
9
  * object is merged into the route config with
7
10
  * the predefined file-based route.
@@ -45,4 +48,4 @@ export const injectRouter = () => {
45
48
  export const injectActivatedRoute = () => {
46
49
  return inject(ActivatedRoute);
47
50
  };
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5lLXJvdXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvZGVmaW5lLXJvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUFvQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFXakQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQXNCLEVBQUUsRUFBRTtJQUN4RCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsR0FBRyxFQUFFO0lBQy9CLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3hCLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLEVBQUU7SUFDdkMsT0FBTyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDaEMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZSBhcyBOZ1JvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG50eXBlIFJvdXRlT21pdHRlZCA9XG4gIHwgJ2NvbXBvbmVudCdcbiAgfCAnbG9hZENvbXBvbmVudCdcbiAgfCAnbG9hZENoaWxkcmVuJ1xuICB8ICdwYXRoJ1xuICB8ICdwYXRoTWF0Y2gnO1xuXG50eXBlIFJlc3RyaWN0ZWRSb3V0ZSA9IE9taXQ8TmdSb3V0ZSwgUm91dGVPbWl0dGVkPjtcblxuLyoqXG4gKiBEZWZpbmVzIGFkZGl0aW9uYWwgcm91dGUgY29uZmlnIG1ldGFkYXRhLiBUaGlzXG4gKiBvYmplY3QgaXMgbWVyZ2VkIGludG8gdGhlIHJvdXRlIGNvbmZpZyB3aXRoXG4gKiB0aGUgcHJlZGVmaW5lZCBmaWxlLWJhc2VkIHJvdXRlLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogYGBgXG4gKiBpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbiAqIGltcG9ydCB7IGRlZmluZVJvdXRlTWV0YSB9IGZyb20gJ0BhbmFsb2dqcy9yb3V0ZXInO1xuICpcbiAqICBleHBvcnQgY29uc3Qgcm91dGVNZXRhID0gZGVmaW5lUm91dGVNZXRhKHtcbiAqICAgIHRpdGxlOiAnV2VsY29tZSdcbiAqICB9KTtcbiAqXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgdGVtcGxhdGU6IGBIb21lYCxcbiAqICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAqIH0pXG4gKiBleHBvcnQgZGVmYXVsdCBjbGFzcyBIb21lQ29tcG9uZW50IHt9XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gcm91dGVcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBjb25zdCBkZWZpbmVSb3V0ZU1ldGEgPSAocm91dGU6IFJlc3RyaWN0ZWRSb3V0ZSkgPT4ge1xuICByZXR1cm4gcm91dGU7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGluc3RhbmNlIG9mIEFuZ3VsYXIgUm91dGVyXG4gKlxuICogQHJldHVybnMgVGhlIHJvdXRlclxuICovXG5leHBvcnQgY29uc3QgaW5qZWN0Um91dGVyID0gKCkgPT4ge1xuICByZXR1cm4gaW5qZWN0KFJvdXRlcik7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGluc3RhbmNlIG9mIHRoZSBBY3RpdmF0ZSBSb3V0ZSBmb3IgdGhlIGNvbXBvbmVudFxuICpcbiAqIEByZXR1cm5zIFRoZSBhY3RpdmF0ZWQgcm91dGVcbiAqL1xuZXhwb3J0IGNvbnN0IGluamVjdEFjdGl2YXRlZFJvdXRlID0gKCkgPT4ge1xuICByZXR1cm4gaW5qZWN0KEFjdGl2YXRlZFJvdXRlKTtcbn07XG4iXX0=
51
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5lLXJvdXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvZGVmaW5lLXJvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUFvQixNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFXakQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQXNCLEVBQUUsRUFBRTtJQUN4RCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsR0FBRyxFQUFFO0lBQy9CLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3hCLENBQUMsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLEVBQUU7SUFDdkMsT0FBTyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDaEMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZSBhcyBOZ1JvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG50eXBlIFJvdXRlT21pdHRlZCA9XG4gIHwgJ2NvbXBvbmVudCdcbiAgfCAnbG9hZENvbXBvbmVudCdcbiAgfCAnbG9hZENoaWxkcmVuJ1xuICB8ICdwYXRoJ1xuICB8ICdwYXRoTWF0Y2gnO1xuXG50eXBlIFJlc3RyaWN0ZWRSb3V0ZSA9IE9taXQ8TmdSb3V0ZSwgUm91dGVPbWl0dGVkPjtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYFJvdXRlTWV0YWAgdHlwZSBpbnN0ZWFkLlxuICogRm9yIG1vcmUgaW5mbyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9hbmFsb2dqcy9hbmFsb2cvaXNzdWVzLzIyM1xuICpcbiAqIERlZmluZXMgYWRkaXRpb25hbCByb3V0ZSBjb25maWcgbWV0YWRhdGEuIFRoaXNcbiAqIG9iamVjdCBpcyBtZXJnZWQgaW50byB0aGUgcm91dGUgY29uZmlnIHdpdGhcbiAqIHRoZSBwcmVkZWZpbmVkIGZpbGUtYmFzZWQgcm91dGUuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICogaW1wb3J0IHsgZGVmaW5lUm91dGVNZXRhIH0gZnJvbSAnQGFuYWxvZ2pzL3JvdXRlcic7XG4gKlxuICogIGV4cG9ydCBjb25zdCByb3V0ZU1ldGEgPSBkZWZpbmVSb3V0ZU1ldGEoe1xuICogICAgdGl0bGU6ICdXZWxjb21lJ1xuICogIH0pO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogICB0ZW1wbGF0ZTogYEhvbWVgLFxuICogICBzdGFuZGFsb25lOiB0cnVlLFxuICogfSlcbiAqIGV4cG9ydCBkZWZhdWx0IGNsYXNzIEhvbWVDb21wb25lbnQge31cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSByb3V0ZVxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGNvbnN0IGRlZmluZVJvdXRlTWV0YSA9IChyb3V0ZTogUmVzdHJpY3RlZFJvdXRlKSA9PiB7XG4gIHJldHVybiByb3V0ZTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaW5zdGFuY2Ugb2YgQW5ndWxhciBSb3V0ZXJcbiAqXG4gKiBAcmV0dXJucyBUaGUgcm91dGVyXG4gKi9cbmV4cG9ydCBjb25zdCBpbmplY3RSb3V0ZXIgPSAoKSA9PiB7XG4gIHJldHVybiBpbmplY3QoUm91dGVyKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaW5zdGFuY2Ugb2YgdGhlIEFjdGl2YXRlIFJvdXRlIGZvciB0aGUgY29tcG9uZW50XG4gKlxuICogQHJldHVybnMgVGhlIGFjdGl2YXRlZCByb3V0ZVxuICovXG5leHBvcnQgY29uc3QgaW5qZWN0QWN0aXZhdGVkUm91dGUgPSAoKSA9PiB7XG4gIHJldHVybiBpbmplY3QoQWN0aXZhdGVkUm91dGUpO1xufTtcbiJdfQ==
@@ -0,0 +1,11 @@
1
+ export function toMarkdownModule(markdownFileFactory) {
2
+ return () => Promise.all([import('@analogjs/content'), markdownFileFactory()]).then(([{ parseRawContentFile, MarkdownComponent }, markdownFile]) => {
3
+ const { content, attributes } = parseRawContentFile(markdownFile);
4
+ const { title, meta } = attributes;
5
+ return {
6
+ default: MarkdownComponent,
7
+ routeMeta: { data: { _analogContent: content }, title, meta },
8
+ };
9
+ });
10
+ }
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24taGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3JvdXRlci9zcmMvbGliL21hcmtkb3duLWhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixtQkFBMEM7SUFFMUMsT0FBTyxHQUFHLEVBQUUsQ0FDVixPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNwRSxDQUFDLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxpQkFBaUIsRUFBRSxFQUFFLFlBQVksQ0FBQyxFQUFFLEVBQUU7UUFDN0QsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNsRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLFVBQVUsQ0FBQztRQUVuQyxPQUFPO1lBQ0wsT0FBTyxFQUFFLGlCQUFpQjtZQUMxQixTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtTQUM5RCxDQUFDO0lBQ0osQ0FBQyxDQUNGLENBQUM7QUFDTixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUm91dGVFeHBvcnQgfSBmcm9tICcuL21vZGVscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB0b01hcmtkb3duTW9kdWxlKFxuICBtYXJrZG93bkZpbGVGYWN0b3J5OiAoKSA9PiBQcm9taXNlPHN0cmluZz5cbik6ICgpID0+IFByb21pc2U8Um91dGVFeHBvcnQ+IHtcbiAgcmV0dXJuICgpID0+XG4gICAgUHJvbWlzZS5hbGwoW2ltcG9ydCgnQGFuYWxvZ2pzL2NvbnRlbnQnKSwgbWFya2Rvd25GaWxlRmFjdG9yeSgpXSkudGhlbihcbiAgICAgIChbeyBwYXJzZVJhd0NvbnRlbnRGaWxlLCBNYXJrZG93bkNvbXBvbmVudCB9LCBtYXJrZG93bkZpbGVdKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY29udGVudCwgYXR0cmlidXRlcyB9ID0gcGFyc2VSYXdDb250ZW50RmlsZShtYXJrZG93bkZpbGUpO1xuICAgICAgICBjb25zdCB7IHRpdGxlLCBtZXRhIH0gPSBhdHRyaWJ1dGVzO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGVmYXVsdDogTWFya2Rvd25Db21wb25lbnQsXG4gICAgICAgICAgcm91dGVNZXRhOiB7IGRhdGE6IHsgX2FuYWxvZ0NvbnRlbnQ6IGNvbnRlbnQgfSwgdGl0bGUsIG1ldGEgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICApO1xufVxuIl19
@@ -0,0 +1,50 @@
1
+ import { inject } from '@angular/core';
2
+ import { Meta } from '@angular/platform-browser';
3
+ import { NavigationEnd, Router } from '@angular/router';
4
+ import { filter } from 'rxjs/operators';
5
+ export const ROUTE_META_TAGS_KEY = Symbol('@analogjs/router Route Meta Tags Key');
6
+ const CHARSET_KEY = 'charset';
7
+ const HTTP_EQUIV_KEY = 'httpEquiv';
8
+ // httpEquiv selector key needs to be in kebab case format
9
+ const HTTP_EQUIV_SELECTOR_KEY = 'http-equiv';
10
+ const NAME_KEY = 'name';
11
+ const PROPERTY_KEY = 'property';
12
+ const CONTENT_KEY = 'content';
13
+ export function updateMetaTagsOnRouteChange() {
14
+ const router = inject(Router);
15
+ const metaService = inject(Meta);
16
+ router.events
17
+ .pipe(filter((event) => event instanceof NavigationEnd))
18
+ .subscribe(() => {
19
+ const metaTagMap = getMetaTagMap(router.routerState.snapshot.root);
20
+ for (const metaTagSelector in metaTagMap) {
21
+ const metaTag = metaTagMap[metaTagSelector];
22
+ metaService.updateTag(metaTag, metaTagSelector);
23
+ }
24
+ });
25
+ }
26
+ function getMetaTagMap(route) {
27
+ const metaTagMap = {};
28
+ let currentRoute = route;
29
+ while (currentRoute) {
30
+ const metaTags = currentRoute.data[ROUTE_META_TAGS_KEY] ?? [];
31
+ for (const metaTag of metaTags) {
32
+ metaTagMap[getMetaTagSelector(metaTag)] = metaTag;
33
+ }
34
+ currentRoute = currentRoute.firstChild;
35
+ }
36
+ return metaTagMap;
37
+ }
38
+ function getMetaTagSelector(metaTag) {
39
+ if (metaTag.name) {
40
+ return `${NAME_KEY}="${metaTag.name}"`;
41
+ }
42
+ if (metaTag.property) {
43
+ return `${PROPERTY_KEY}="${metaTag.property}"`;
44
+ }
45
+ if (metaTag.httpEquiv) {
46
+ return `${HTTP_EQUIV_SELECTOR_KEY}="${metaTag.httpEquiv}"`;
47
+ }
48
+ return CHARSET_KEY;
49
+ }
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS10YWdzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvbWV0YS10YWdzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkMsT0FBTyxFQUFFLElBQUksRUFBK0IsTUFBTSwyQkFBMkIsQ0FBQztBQUM5RSxPQUFPLEVBQTBCLGFBQWEsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsTUFBTSxDQUN2QyxzQ0FBc0MsQ0FDdkMsQ0FBQztBQUVGLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQztBQUM5QixNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUM7QUFDbkMsMERBQTBEO0FBQzFELE1BQU0sdUJBQXVCLEdBQUcsWUFBWSxDQUFDO0FBQzdDLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQztBQUN4QixNQUFNLFlBQVksR0FBRyxVQUFVLENBQUM7QUFDaEMsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDO0FBOEI5QixNQUFNLFVBQVUsMkJBQTJCO0lBQ3pDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM5QixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFakMsTUFBTSxDQUFDLE1BQU07U0FDVixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLFlBQVksYUFBYSxDQUFDLENBQUM7U0FDdkQsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNkLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVuRSxLQUFLLE1BQU0sZUFBZSxJQUFJLFVBQVUsRUFBRTtZQUN4QyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQ3hCLGVBQWtDLENBQ3RCLENBQUM7WUFDZixXQUFXLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxlQUFlLENBQUMsQ0FBQztTQUNqRDtJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLEtBQTZCO0lBQ2xELE1BQU0sVUFBVSxHQUFHLEVBQWdCLENBQUM7SUFDcEMsSUFBSSxZQUFZLEdBQWtDLEtBQUssQ0FBQztJQUV4RCxPQUFPLFlBQVksRUFBRTtRQUNuQixNQUFNLFFBQVEsR0FBYyxZQUFZLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3pFLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFO1lBQzlCLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztTQUNuRDtRQUVELFlBQVksR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDO0tBQ3hDO0lBRUQsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQUVELFNBQVMsa0JBQWtCLENBQUMsT0FBZ0I7SUFDMUMsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFO1FBQ2hCLE9BQU8sR0FBRyxRQUFRLEtBQUssT0FBTyxDQUFDLElBQUksR0FBRyxDQUFDO0tBQ3hDO0lBRUQsSUFBSSxPQUFPLENBQUMsUUFBUSxFQUFFO1FBQ3BCLE9BQU8sR0FBRyxZQUFZLEtBQUssT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDO0tBQ2hEO0lBRUQsSUFBSSxPQUFPLENBQUMsU0FBUyxFQUFFO1FBQ3JCLE9BQU8sR0FBRyx1QkFBdUIsS0FBSyxPQUFPLENBQUMsU0FBUyxHQUFHLENBQUM7S0FDNUQ7SUFFRCxPQUFPLFdBQVcsQ0FBQztBQUNyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNZXRhLCBNZXRhRGVmaW5pdGlvbiBhcyBOZ01ldGFUYWcgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlU25hcHNob3QsIE5hdmlnYXRpb25FbmQsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmV4cG9ydCBjb25zdCBST1VURV9NRVRBX1RBR1NfS0VZID0gU3ltYm9sKFxuICAnQGFuYWxvZ2pzL3JvdXRlciBSb3V0ZSBNZXRhIFRhZ3MgS2V5J1xuKTtcblxuY29uc3QgQ0hBUlNFVF9LRVkgPSAnY2hhcnNldCc7XG5jb25zdCBIVFRQX0VRVUlWX0tFWSA9ICdodHRwRXF1aXYnO1xuLy8gaHR0cEVxdWl2IHNlbGVjdG9yIGtleSBuZWVkcyB0byBiZSBpbiBrZWJhYiBjYXNlIGZvcm1hdFxuY29uc3QgSFRUUF9FUVVJVl9TRUxFQ1RPUl9LRVkgPSAnaHR0cC1lcXVpdic7XG5jb25zdCBOQU1FX0tFWSA9ICduYW1lJztcbmNvbnN0IFBST1BFUlRZX0tFWSA9ICdwcm9wZXJ0eSc7XG5jb25zdCBDT05URU5UX0tFWSA9ICdjb250ZW50JztcblxuZXhwb3J0IHR5cGUgTWV0YVRhZyA9XG4gIHwgKENoYXJzZXRNZXRhVGFnICYgRXhjbHVkZVJlc3RNZXRhVGFnS2V5czx0eXBlb2YgQ0hBUlNFVF9LRVk+KVxuICB8IChIdHRwRXF1aXZNZXRhVGFnICYgRXhjbHVkZVJlc3RNZXRhVGFnS2V5czx0eXBlb2YgSFRUUF9FUVVJVl9LRVk+KVxuICB8IChOYW1lTWV0YVRhZyAmIEV4Y2x1ZGVSZXN0TWV0YVRhZ0tleXM8dHlwZW9mIE5BTUVfS0VZPilcbiAgfCAoUHJvcGVydHlNZXRhVGFnICYgRXhjbHVkZVJlc3RNZXRhVGFnS2V5czx0eXBlb2YgUFJPUEVSVFlfS0VZPik7XG5cbnR5cGUgQ2hhcnNldE1ldGFUYWcgPSB7IFtDSEFSU0VUX0tFWV06IHN0cmluZyB9O1xudHlwZSBIdHRwRXF1aXZNZXRhVGFnID0geyBbSFRUUF9FUVVJVl9LRVldOiBzdHJpbmc7IFtDT05URU5UX0tFWV06IHN0cmluZyB9O1xudHlwZSBOYW1lTWV0YVRhZyA9IHsgW05BTUVfS0VZXTogc3RyaW5nOyBbQ09OVEVOVF9LRVldOiBzdHJpbmcgfTtcbnR5cGUgUHJvcGVydHlNZXRhVGFnID0geyBbUFJPUEVSVFlfS0VZXTogc3RyaW5nOyBbQ09OVEVOVF9LRVldOiBzdHJpbmcgfTtcblxudHlwZSBNZXRhVGFnS2V5ID1cbiAgfCB0eXBlb2YgQ0hBUlNFVF9LRVlcbiAgfCB0eXBlb2YgSFRUUF9FUVVJVl9LRVlcbiAgfCB0eXBlb2YgTkFNRV9LRVlcbiAgfCB0eXBlb2YgUFJPUEVSVFlfS0VZO1xudHlwZSBFeGNsdWRlUmVzdE1ldGFUYWdLZXlzPEtleSBleHRlbmRzIE1ldGFUYWdLZXk+ID0ge1xuICBbSyBpbiBFeGNsdWRlPE1ldGFUYWdLZXksIEtleT5dPzogbmV2ZXI7XG59O1xuXG50eXBlIE1ldGFUYWdTZWxlY3RvciA9XG4gIHwgdHlwZW9mIENIQVJTRVRfS0VZXG4gIHwgYCR7XG4gICAgICB8IHR5cGVvZiBIVFRQX0VRVUlWX1NFTEVDVE9SX0tFWVxuICAgICAgfCB0eXBlb2YgTkFNRV9LRVlcbiAgICAgIHwgdHlwZW9mIFBST1BFUlRZX0tFWX09XCIke3N0cmluZ31cImA7XG50eXBlIE1ldGFUYWdNYXAgPSBSZWNvcmQ8TWV0YVRhZ1NlbGVjdG9yLCBNZXRhVGFnPjtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZU1ldGFUYWdzT25Sb3V0ZUNoYW5nZSgpOiB2b2lkIHtcbiAgY29uc3Qgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XG4gIGNvbnN0IG1ldGFTZXJ2aWNlID0gaW5qZWN0KE1ldGEpO1xuXG4gIHJvdXRlci5ldmVudHNcbiAgICAucGlwZShmaWx0ZXIoKGV2ZW50KSA9PiBldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQpKVxuICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgY29uc3QgbWV0YVRhZ01hcCA9IGdldE1ldGFUYWdNYXAocm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnJvb3QpO1xuXG4gICAgICBmb3IgKGNvbnN0IG1ldGFUYWdTZWxlY3RvciBpbiBtZXRhVGFnTWFwKSB7XG4gICAgICAgIGNvbnN0IG1ldGFUYWcgPSBtZXRhVGFnTWFwW1xuICAgICAgICAgIG1ldGFUYWdTZWxlY3RvciBhcyBNZXRhVGFnU2VsZWN0b3JcbiAgICAgICAgXSBhcyBOZ01ldGFUYWc7XG4gICAgICAgIG1ldGFTZXJ2aWNlLnVwZGF0ZVRhZyhtZXRhVGFnLCBtZXRhVGFnU2VsZWN0b3IpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRNZXRhVGFnTWFwKHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogTWV0YVRhZ01hcCB7XG4gIGNvbnN0IG1ldGFUYWdNYXAgPSB7fSBhcyBNZXRhVGFnTWFwO1xuICBsZXQgY3VycmVudFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90IHwgbnVsbCA9IHJvdXRlO1xuXG4gIHdoaWxlIChjdXJyZW50Um91dGUpIHtcbiAgICBjb25zdCBtZXRhVGFnczogTWV0YVRhZ1tdID0gY3VycmVudFJvdXRlLmRhdGFbUk9VVEVfTUVUQV9UQUdTX0tFWV0gPz8gW107XG4gICAgZm9yIChjb25zdCBtZXRhVGFnIG9mIG1ldGFUYWdzKSB7XG4gICAgICBtZXRhVGFnTWFwW2dldE1ldGFUYWdTZWxlY3RvcihtZXRhVGFnKV0gPSBtZXRhVGFnO1xuICAgIH1cblxuICAgIGN1cnJlbnRSb3V0ZSA9IGN1cnJlbnRSb3V0ZS5maXJzdENoaWxkO1xuICB9XG5cbiAgcmV0dXJuIG1ldGFUYWdNYXA7XG59XG5cbmZ1bmN0aW9uIGdldE1ldGFUYWdTZWxlY3RvcihtZXRhVGFnOiBNZXRhVGFnKTogTWV0YVRhZ1NlbGVjdG9yIHtcbiAgaWYgKG1ldGFUYWcubmFtZSkge1xuICAgIHJldHVybiBgJHtOQU1FX0tFWX09XCIke21ldGFUYWcubmFtZX1cImA7XG4gIH1cblxuICBpZiAobWV0YVRhZy5wcm9wZXJ0eSkge1xuICAgIHJldHVybiBgJHtQUk9QRVJUWV9LRVl9PVwiJHttZXRhVGFnLnByb3BlcnR5fVwiYDtcbiAgfVxuXG4gIGlmIChtZXRhVGFnLmh0dHBFcXVpdikge1xuICAgIHJldHVybiBgJHtIVFRQX0VRVUlWX1NFTEVDVE9SX0tFWX09XCIke21ldGFUYWcuaHR0cEVxdWl2fVwiYDtcbiAgfVxuXG4gIHJldHVybiBDSEFSU0VUX0tFWTtcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvbW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBDYW5BY3RpdmF0ZUNoaWxkRm4sXG4gIENhbkFjdGl2YXRlRm4sXG4gIENhbkRlYWN0aXZhdGVGbixcbiAgQ2FuTWF0Y2hGbixcbiAgUmVzb2x2ZUZuLFxuICBSb3V0ZSxcbn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuaW1wb3J0IHsgZGVmaW5lUm91dGVNZXRhIH0gZnJvbSAnLi9kZWZpbmUtcm91dGUnO1xuaW1wb3J0IHsgTWV0YVRhZyB9IGZyb20gJy4vbWV0YS10YWdzJztcblxudHlwZSBPbWl0dGVkUm91dGVQcm9wcyA9XG4gIHwgJ3BhdGgnXG4gIHwgJ21hdGNoZXInXG4gIHwgJ2NvbXBvbmVudCdcbiAgfCAnbG9hZENvbXBvbmVudCdcbiAgfCAnY2hpbGRyZW4nXG4gIHwgJ2xvYWRDaGlsZHJlbidcbiAgfCAnY2FuTG9hZCdcbiAgfCAnb3V0bGV0JztcblxuZXhwb3J0IHR5cGUgUm91dGVDb25maWcgPSBPbWl0PFJvdXRlLCBPbWl0dGVkUm91dGVQcm9wcz47XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVmYXVsdFJvdXRlTWV0YVxuICBleHRlbmRzIE9taXQ8Um91dGUsIE9taXR0ZWRSb3V0ZVByb3BzIHwga2V5b2YgUmVkaXJlY3RSb3V0ZU1ldGE+IHtcbiAgY2FuQWN0aXZhdGU/OiBDYW5BY3RpdmF0ZUZuW107XG4gIGNhbkFjdGl2YXRlQ2hpbGQ/OiBDYW5BY3RpdmF0ZUNoaWxkRm5bXTtcbiAgY2FuRGVhY3RpdmF0ZT86IENhbkRlYWN0aXZhdGVGbjx1bmtub3duPltdO1xuICBjYW5NYXRjaD86IENhbk1hdGNoRm5bXTtcbiAgcmVzb2x2ZT86IHsgW2tleTogc3RyaW5nIHwgc3ltYm9sXTogUmVzb2x2ZUZuPHVua25vd24+IH07XG4gIHRpdGxlPzogc3RyaW5nIHwgUmVzb2x2ZUZuPHN0cmluZz47XG4gIG1ldGE/OiBNZXRhVGFnW10gfCBSZXNvbHZlRm48TWV0YVRhZ1tdPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWRpcmVjdFJvdXRlTWV0YSB7XG4gIHJlZGlyZWN0VG86IHN0cmluZztcbiAgcGF0aE1hdGNoPzogUm91dGVbJ3BhdGhNYXRjaCddO1xufVxuXG5leHBvcnQgdHlwZSBSb3V0ZU1ldGEgPVxuICAvLyBlbmZvcmNlIGV4Y2x1c2l2ZSB1bmlvblxuICAoRGVmYXVsdFJvdXRlTWV0YSAmIHsgcmVkaXJlY3RUbz86IG5ldmVyIH0pIHwgUmVkaXJlY3RSb3V0ZU1ldGE7XG5cbmV4cG9ydCB0eXBlIFJvdXRlRXhwb3J0ID0ge1xuICBkZWZhdWx0OiBUeXBlPHVua25vd24+O1xuICByb3V0ZU1ldGE/OiBSb3V0ZU1ldGEgfCBSZXR1cm5UeXBlPHR5cGVvZiBkZWZpbmVSb3V0ZU1ldGE+O1xufTtcbiJdfQ==
@@ -0,0 +1,25 @@
1
+ import { ENVIRONMENT_INITIALIZER, makeEnvironmentProviders, } from '@angular/core';
2
+ import { provideRouter } from '@angular/router';
3
+ import { routes } from './routes';
4
+ import { updateMetaTagsOnRouteChange } from './meta-tags';
5
+ /**
6
+ * Sets up providers for the Angular router, and registers
7
+ * file-based routes. Additional features can be provided
8
+ * to further configure the behavior of the router.
9
+ *
10
+ * @param features
11
+ * @returns Providers and features to configure the router with routes
12
+ */
13
+ export function provideFileRouter(...features) {
14
+ return makeEnvironmentProviders([
15
+ // TODO: remove type casting after Angular >=15.1.1 upgrade
16
+ // https://github.com/angular/angular/pull/48720
17
+ provideRouter(routes, ...features).ɵproviders,
18
+ {
19
+ provide: ENVIRONMENT_INITIALIZER,
20
+ multi: true,
21
+ useValue: () => updateMetaTagsOnRouteChange(),
22
+ },
23
+ ]);
24
+ }
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZS1maWxlLXJvdXRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3JvdXRlci9zcmMvbGliL3Byb3ZpZGUtZmlsZS1yb3V0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUV2Qix3QkFBd0IsR0FFekIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBa0IsTUFBTSxpQkFBaUIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ2xDLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUUxRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixHQUFHLFFBQTBCO0lBRTdCLE9BQU8sd0JBQXdCLENBQUM7UUFDOUIsMkRBQTJEO1FBQzNELGdEQUFnRDtRQUU5QyxhQUFhLENBQUMsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUdsQyxDQUFDLFVBQVU7UUFDWjtZQUNFLE9BQU8sRUFBRSx1QkFBdUI7WUFDaEMsS0FBSyxFQUFFLElBQUk7WUFDWCxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsMkJBQTJCLEVBQUU7U0FDOUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRU5WSVJPTk1FTlRfSU5JVElBTElaRVIsXG4gIEVudmlyb25tZW50UHJvdmlkZXJzLFxuICBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMsXG4gIFByb3ZpZGVyLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHByb3ZpZGVSb3V0ZXIsIFJvdXRlckZlYXR1cmVzIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcblxuaW1wb3J0IHsgcm91dGVzIH0gZnJvbSAnLi9yb3V0ZXMnO1xuaW1wb3J0IHsgdXBkYXRlTWV0YVRhZ3NPblJvdXRlQ2hhbmdlIH0gZnJvbSAnLi9tZXRhLXRhZ3MnO1xuXG4vKipcbiAqIFNldHMgdXAgcHJvdmlkZXJzIGZvciB0aGUgQW5ndWxhciByb3V0ZXIsIGFuZCByZWdpc3RlcnNcbiAqIGZpbGUtYmFzZWQgcm91dGVzLiBBZGRpdGlvbmFsIGZlYXR1cmVzIGNhbiBiZSBwcm92aWRlZFxuICogdG8gZnVydGhlciBjb25maWd1cmUgdGhlIGJlaGF2aW9yIG9mIHRoZSByb3V0ZXIuXG4gKlxuICogQHBhcmFtIGZlYXR1cmVzXG4gKiBAcmV0dXJucyBQcm92aWRlcnMgYW5kIGZlYXR1cmVzIHRvIGNvbmZpZ3VyZSB0aGUgcm91dGVyIHdpdGggcm91dGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlRmlsZVJvdXRlcihcbiAgLi4uZmVhdHVyZXM6IFJvdXRlckZlYXR1cmVzW11cbik6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAgLy8gVE9ETzogcmVtb3ZlIHR5cGUgY2FzdGluZyBhZnRlciBBbmd1bGFyID49MTUuMS4xIHVwZ3JhZGVcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL3B1bGwvNDg3MjBcbiAgICAoXG4gICAgICBwcm92aWRlUm91dGVyKHJvdXRlcywgLi4uZmVhdHVyZXMpIGFzIHVua25vd24gYXMge1xuICAgICAgICDJtXByb3ZpZGVyczogUHJvdmlkZXJbXTtcbiAgICAgIH1cbiAgICApLsm1cHJvdmlkZXJzLFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IEVOVklST05NRU5UX0lOSVRJQUxJWkVSLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgICB1c2VWYWx1ZTogKCkgPT4gdXBkYXRlTWV0YVRhZ3NPblJvdXRlQ2hhbmdlKCksXG4gICAgfSxcbiAgXSk7XG59XG4iXX0=
@@ -0,0 +1,24 @@
1
+ import { ROUTE_META_TAGS_KEY } from './meta-tags';
2
+ export function toRouteConfig(routeMeta) {
3
+ if (!routeMeta) {
4
+ return {};
5
+ }
6
+ if (isRedirectRouteMeta(routeMeta)) {
7
+ return routeMeta;
8
+ }
9
+ const { meta, ...routeConfig } = routeMeta;
10
+ if (Array.isArray(meta)) {
11
+ routeConfig.data = { ...routeConfig.data, [ROUTE_META_TAGS_KEY]: meta };
12
+ }
13
+ else if (typeof meta === 'function') {
14
+ routeConfig.resolve = {
15
+ ...routeConfig.resolve,
16
+ [ROUTE_META_TAGS_KEY]: meta,
17
+ };
18
+ }
19
+ return routeConfig;
20
+ }
21
+ function isRedirectRouteMeta(routeMeta) {
22
+ return !!routeMeta.redirectTo;
23
+ }
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvcm91dGUtY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUVsRCxNQUFNLFVBQVUsYUFBYSxDQUFDLFNBQWdDO0lBQzVELElBQUksQ0FBQyxTQUFTLEVBQUU7UUFDZCxPQUFPLEVBQUUsQ0FBQztLQUNYO0lBRUQsSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsRUFBRTtRQUNsQyxPQUFPLFNBQVMsQ0FBQztLQUNsQjtJQUVELE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxXQUFXLEVBQUUsR0FBRyxTQUFTLENBQUM7SUFFM0MsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ3ZCLFdBQVcsQ0FBQyxJQUFJLEdBQUcsRUFBRSxHQUFHLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDO0tBQ3pFO1NBQU0sSUFBSSxPQUFPLElBQUksS0FBSyxVQUFVLEVBQUU7UUFDckMsV0FBVyxDQUFDLE9BQU8sR0FBRztZQUNwQixHQUFHLFdBQVcsQ0FBQyxPQUFPO1lBQ3RCLENBQUMsbUJBQW1CLENBQUMsRUFBRSxJQUFJO1NBQzVCLENBQUM7S0FDSDtJQUVELE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxTQUFTLG1CQUFtQixDQUMxQixTQUFvQjtJQUVwQixPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDO0FBQ2hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZWRpcmVjdFJvdXRlTWV0YSwgUm91dGVDb25maWcsIFJvdXRlTWV0YSB9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IFJPVVRFX01FVEFfVEFHU19LRVkgfSBmcm9tICcuL21ldGEtdGFncyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB0b1JvdXRlQ29uZmlnKHJvdXRlTWV0YTogUm91dGVNZXRhIHwgdW5kZWZpbmVkKTogUm91dGVDb25maWcge1xuICBpZiAoIXJvdXRlTWV0YSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGlmIChpc1JlZGlyZWN0Um91dGVNZXRhKHJvdXRlTWV0YSkpIHtcbiAgICByZXR1cm4gcm91dGVNZXRhO1xuICB9XG5cbiAgY29uc3QgeyBtZXRhLCAuLi5yb3V0ZUNvbmZpZyB9ID0gcm91dGVNZXRhO1xuXG4gIGlmIChBcnJheS5pc0FycmF5KG1ldGEpKSB7XG4gICAgcm91dGVDb25maWcuZGF0YSA9IHsgLi4ucm91dGVDb25maWcuZGF0YSwgW1JPVVRFX01FVEFfVEFHU19LRVldOiBtZXRhIH07XG4gIH0gZWxzZSBpZiAodHlwZW9mIG1ldGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICByb3V0ZUNvbmZpZy5yZXNvbHZlID0ge1xuICAgICAgLi4ucm91dGVDb25maWcucmVzb2x2ZSxcbiAgICAgIFtST1VURV9NRVRBX1RBR1NfS0VZXTogbWV0YSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHJvdXRlQ29uZmlnO1xufVxuXG5mdW5jdGlvbiBpc1JlZGlyZWN0Um91dGVNZXRhKFxuICByb3V0ZU1ldGE6IFJvdXRlTWV0YVxuKTogcm91dGVNZXRhIGlzIFJlZGlyZWN0Um91dGVNZXRhIHtcbiAgcmV0dXJuICEhcm91dGVNZXRhLnJlZGlyZWN0VG87XG59XG4iXX0=
@@ -1,5 +1,14 @@
1
1
  /// <reference types="vite/client" />
2
- const FILES = import.meta.glob(['/app/routes/**/*.ts']);
2
+ import { toRouteConfig } from './route-config';
3
+ import { toMarkdownModule } from './markdown-helpers';
4
+ const FILES = import.meta.glob([
5
+ '/app/routes/**/*.ts',
6
+ '/src/app/routes/**/*.ts',
7
+ '/src/app/pages/**/*.page.ts',
8
+ ]);
9
+ const CONTENT_FILES = import.meta.glob(['/src/app/routes/**/*.md', '/src/app/pages/**/*.md'], {
10
+ as: 'raw',
11
+ });
3
12
  /**
4
13
  * Function used to parse list of files and return
5
14
  * configuration of routes.
@@ -10,15 +19,19 @@ const FILES = import.meta.glob(['/app/routes/**/*.ts']);
10
19
  export function getRoutes(files) {
11
20
  const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);
12
21
  const routeConfigs = ROUTES.reduce((routes, key) => {
13
- const module = files[key];
22
+ const module = key.endsWith('.md')
23
+ ? toMarkdownModule(files[key])
24
+ : files[key];
14
25
  const segments = key
15
- .replace(/\/app\/routes|\.(js|ts)$/g, '')
26
+ .replace(/^\/(.*?)\/routes|^\/(.*?)\/pages|\/app\/routes|\.page|\.(js|ts|md)$/g, '')
16
27
  .replace(/\[\.{3}.+\]/, '**')
17
28
  .replace(/\[([^\]]+)\]/g, ':$1')
18
29
  .split('/')
19
30
  .filter(Boolean);
20
31
  segments.reduce((parent, segment, index) => {
21
- const path = segment.replace(/index/g, '').replace('.', '/');
32
+ const path = segment
33
+ .replace(/index|^\(.*?\)$/g, '')
34
+ .replace(/\./g, '/');
22
35
  const isIndex = !path;
23
36
  const isCatchall = path === '**';
24
37
  const pathMatch = isIndex ? 'full' : 'prefix';
@@ -40,7 +53,7 @@ export function getRoutes(files) {
40
53
  {
41
54
  path: '',
42
55
  component: m.default,
43
- ...m.routeMeta,
56
+ ...toRouteConfig(m.routeMeta),
44
57
  },
45
58
  ]),
46
59
  };
@@ -66,7 +79,7 @@ export function getRoutes(files) {
66
79
  {
67
80
  path: '',
68
81
  component: m.default,
69
- ...m.routeMeta,
82
+ ...toRouteConfig(m.routeMeta),
70
83
  },
71
84
  ]),
72
85
  });
@@ -83,7 +96,7 @@ export function getRoutes(files) {
83
96
  {
84
97
  path: '',
85
98
  component: m.default,
86
- ...m.routeMeta,
99
+ ...toRouteConfig(m.routeMeta),
87
100
  },
88
101
  ]),
89
102
  });
@@ -95,7 +108,7 @@ export function getRoutes(files) {
95
108
  {
96
109
  path: '',
97
110
  children: parent._children,
98
- ...m.routeMeta,
111
+ ...toRouteConfig(m.routeMeta),
99
112
  },
100
113
  ];
101
114
  });
@@ -106,5 +119,5 @@ export function getRoutes(files) {
106
119
  }, []);
107
120
  return routeConfigs;
108
121
  }
109
- export const routes = [...getRoutes(FILES)];
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvcm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHFDQUFxQztBQVdyQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBYyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQztBQUVyRTs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLEtBQWlEO0lBQ3pFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFdEUsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FDaEMsQ0FBQyxNQUFlLEVBQUUsR0FBVyxFQUFFLEVBQUU7UUFDL0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTFCLE1BQU0sUUFBUSxHQUFHLEdBQUc7YUFDakIsT0FBTyxDQUFDLDJCQUEyQixFQUFFLEVBQUUsQ0FBQzthQUN4QyxPQUFPLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQzthQUM1QixPQUFPLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQzthQUMvQixLQUFLLENBQUMsR0FBRyxDQUFDO2FBQ1YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRW5CLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3pDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDN0Qs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Q0FBQyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgdHlwZXM9XCJ2aXRlL2NsaWVudFwiIC8+XG5cbmltcG9ydCB0eXBlIHsgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHR5cGUgeyBSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBkZWZpbmVSb3V0ZU1ldGEgfSBmcm9tICcuL2RlZmluZS1yb3V0ZSc7XG5cbmV4cG9ydCB0eXBlIFJvdXRlRXhwb3J0ID0ge1xuICBkZWZhdWx0OiBUeXBlPHVua25vd24+O1xuICByb3V0ZU1ldGE/OiBSZXR1cm5UeXBlPHR5cGVvZiBkZWZpbmVSb3V0ZU1ldGE+O1xufTtcblxuY29uc3QgRklMRVMgPSBpbXBvcnQubWV0YS5nbG9iPFJvdXRlRXhwb3J0PihbJy9hcHAvcm91dGVzLyoqLyoudHMnXSk7XG5cbi8qKlxuICogRnVuY3Rpb24gdXNlZCB0byBwYXJzZSBsaXN0IG9mIGZpbGVzIGFuZCByZXR1cm5cbiAqIGNvbmZpZ3VyYXRpb24gb2Ygcm91dGVzLlxuICpcbiAqIEBwYXJhbSBmaWxlc1xuICogQHJldHVybnMgQXJyYXkgb2Ygcm91dGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSb3V0ZXMoZmlsZXM6IFJlY29yZDxzdHJpbmcsICgpID0+IFByb21pc2U8Um91dGVFeHBvcnQ+Pikge1xuICBjb25zdCBST1VURVMgPSBPYmplY3Qua2V5cyhmaWxlcykuc29ydCgoYSwgYikgPT4gYS5sZW5ndGggLSBiLmxlbmd0aCk7XG5cbiAgY29uc3Qgcm91dGVDb25maWdzID0gUk9VVEVTLnJlZHVjZTxSb3V0ZVtdPihcbiAgICAocm91dGVzOiBSb3V0ZVtdLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbW9kdWxlID0gZmlsZXNba2V5XTtcblxuICAgICAgY29uc3Qgc2VnbWVudHMgPSBrZXlcbiAgICAgICAgLnJlcGxhY2UoL1xcL2FwcFxcL3JvdXRlc3xcXC4oanN8dHMpJC9nLCAnJylcbiAgICAgICAgLnJlcGxhY2UoL1xcW1xcLnszfS4rXFxdLywgJyoqJylcbiAgICAgICAgLnJlcGxhY2UoL1xcWyhbXlxcXV0rKVxcXS9nLCAnOiQxJylcbiAgICAgICAgLnNwbGl0KCcvJylcbiAgICAgICAgLmZpbHRlcihCb29sZWFuKTtcblxuICAgICAgc2VnbWVudHMucmVkdWNlKChwYXJlbnQsIHNlZ21lbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHBhdGggPSBzZWdtZW50LnJlcGxhY2UoL2luZGV4L2csICcnKS5yZXBsYWNlKCcuJywgJy8nKTtcbiAgICAgICAgY29uc3QgaXNJbmRleCA9ICFwYXRoO1xuICAgICAgICBjb25zdCBpc0NhdGNoYWxsID0gcGF0aCA9PT0gJyoqJztcbiAgICAgICAgY29uc3QgcGF0aE1hdGNoID0gaXNJbmRleCA/ICdmdWxsJyA6ICdwcmVmaXgnO1xuICAgICAgICBjb25zdCByb290ID0gaW5kZXggPT09IDA7XG4gICAgICAgIGNvbnN0IGxlYWYgPSBpbmRleCA9PT0gc2VnbWVudHMubGVuZ3RoIC0gMSAmJiBzZWdtZW50cy5sZW5ndGggPiAxO1xuICAgICAgICBjb25zdCBub2RlID0gIXJvb3QgJiYgIWxlYWY7XG4gICAgICAgIGNvbnN0IGluc2VydCA9IC9eXFx3fFxcLy8udGVzdChwYXRoKSAmJiAhaXNDYXRjaGFsbCA/ICd1bnNoaWZ0JyA6ICdwdXNoJztcblxuICAgICAgICBpZiAocm9vdCkge1xuICAgICAgICAgIGNvbnN0IGR5bmFtaWMgPSBwYXRoLnN0YXJ0c1dpdGgoJzonKTtcbiAgICAgICAgICBpZiAoZHluYW1pYykgcmV0dXJuIHBhcmVudDtcblxuICAgICAgICAgIGNvbnN0IGxhc3QgPSBzZWdtZW50cy5sZW5ndGggPT09IDE7XG4gICAgICAgICAgaWYgKGxhc3QpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld1JvdXRlID0ge1xuICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICBwYXRoTWF0Y2gsXG4gICAgICAgICAgICAgIF9tb2R1bGU6ICgpID0+IG1vZHVsZSgpLFxuICAgICAgICAgICAgICBsb2FkQ2hpbGRyZW46ICgpID0+XG4gICAgICAgICAgICAgICAgbW9kdWxlKCkudGhlbigobSkgPT4gW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50OiBtLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIC4uLm0ucm91dGVNZXRhLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJvdXRlcz8uW2luc2VydF0obmV3Um91dGUgYXMgUm91dGUpO1xuICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm9vdCB8fCBub2RlKSB7XG4gICAgICAgICAgY29uc3QgY3VycmVudCA9IHJvb3QgPyByb3V0ZXMgOiBwYXJlbnQuX2NoaWxkcmVuO1xuICAgICAgICAgIGNvbnN0IGZvdW5kID0gY3VycmVudD8uZmluZCgocm91dGU6IGFueSkgPT4gcm91dGUucGF0aCA9PT0gcGF0aCk7XG5cbiAgICAgICAgICBpZiAoZm91bmQpIHtcbiAgICAgICAgICAgIGlmICghZm91bmQuX2NoaWxkcmVuKSB7XG4gICAgICAgICAgICAgIGZvdW5kLl9jaGlsZHJlbiA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3VuZC5wYXRoTWF0Y2ggPSBwYXRoTWF0Y2g7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGN1cnJlbnQ/LltpbnNlcnRdKHtcbiAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgcGF0aE1hdGNoLFxuICAgICAgICAgICAgICBfbW9kdWxlOiAoKSA9PiBtb2R1bGUoKSxcbiAgICAgICAgICAgICAgbG9hZENoaWxkcmVuOiAoKSA9PlxuICAgICAgICAgICAgICAgIG1vZHVsZSgpLnRoZW4oKG0pID0+IFtcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudDogbS5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICAuLi5tLnJvdXRlTWV0YSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgZm91bmQgfHxcbiAgICAgICAgICAgIChjdXJyZW50Py5baW5zZXJ0ID09PSAndW5zaGlmdCcgPyAwIDogY3VycmVudC5sZW5ndGggLSAxXSBhcyBSb3V0ZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxlYWYpIHtcbiAgICAgICAgICBwYXJlbnQ/Ll9jaGlsZHJlbj8uW2luc2VydF0oe1xuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHBhdGhNYXRjaCxcbiAgICAgICAgICAgIF9tb2R1bGU6ICgpID0+IG1vZHVsZSgpLFxuICAgICAgICAgICAgbG9hZENoaWxkcmVuOiAoKSA9PlxuICAgICAgICAgICAgICBtb2R1bGUoKS50aGVuKChtKSA9PiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgICAgICAgICBjb21wb25lbnQ6IG0uZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgIC4uLm0ucm91dGVNZXRhLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0pLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmVudC5fY2hpbGRyZW4pIHtcbiAgICAgICAgICBwYXJlbnQubG9hZENvbXBvbmVudCA9ICgpID0+XG4gICAgICAgICAgICBwYXJlbnQuX21vZHVsZSgpLnRoZW4oKG06IFJvdXRlRXhwb3J0KSA9PiBtLmRlZmF1bHQpO1xuICAgICAgICAgIHBhcmVudC5sb2FkQ2hpbGRyZW4gPSAoKSA9PlxuICAgICAgICAgICAgcGFyZW50Ll9tb2R1bGUoKS50aGVuKChtOiBSb3V0ZUV4cG9ydCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHBhdGg6ICcnLFxuICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IHBhcmVudC5fY2hpbGRyZW4sXG4gICAgICAgICAgICAgICAgICAuLi5tLnJvdXRlTWV0YSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgICAgfSwge30gYXMgUm91dGUgJiB7IF9tb2R1bGU6ICgpID0+IFByb21pc2U8Um91dGVFeHBvcnQ+OyBfY2hpbGRyZW46IGFueVtdIH0pO1xuXG4gICAgICByZXR1cm4gcm91dGVzO1xuICAgIH0sXG4gICAgW11cbiAgKTtcblxuICByZXR1cm4gcm91dGVDb25maWdzO1xufVxuXG5leHBvcnQgY29uc3Qgcm91dGVzOiBSb3V0ZVtdID0gWy4uLmdldFJvdXRlcyhGSUxFUyldO1xuIl19
122
+ export const routes = [...getRoutes({ ...FILES, ...CONTENT_FILES })];
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9saWIvcm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHFDQUFxQztBQUtyQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFdEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQWM7SUFDMUMscUJBQXFCO0lBQ3JCLHlCQUF5QjtJQUN6Qiw2QkFBNkI7Q0FDOUIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQ3BDLENBQUMseUJBQXlCLEVBQUUsd0JBQXdCLENBQUMsRUFDckQ7SUFDRSxFQUFFLEVBQUUsS0FBSztDQUNWLENBQ0YsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQ3ZCLEtBQTBEO0lBRTFELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFdEUsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FDaEMsQ0FBQyxNQUFlLEVBQUUsR0FBVyxFQUFFLEVBQUU7UUFDL0IsTUFBTSxNQUFNLEdBQStCLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQzVELENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUEwQixDQUFDO1lBQ3ZELENBQUMsQ0FBRSxLQUFLLENBQUMsR0FBRyxDQUFnQyxDQUFDO1FBRS9DLE1BQU0sUUFBUSxHQUFHLEdBQUc7YUFDakIsT0FBTyxDQUNOLHNFQUFzRSxFQUN0RSxFQUFFLENBQ0g7YUFDQSxPQUFPLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQzthQUM1QixPQUFPLENBQUMsZUFBZSxFQUFFLEtBQUssQ0FBQzthQUMvQixLQUFLLENBQUMsR0FBRyxDQUFDO2FBQ1YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRW5CLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3pDLE1BQU0sSUFBSSxHQUFHLE9BQU87aUJBQ2pCLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7aUJBQy9CLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDdkIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDdEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxLQUFLLElBQUksQ0FBQztZQUNqQyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzlDLE1BQU0sSUFBSSxHQUFHLEtBQUssS0FBSyxDQUFDLENBQUM7WUFDekIsTUFBTSxJQUFJLEdBQUcsS0FBSyxLQUFLLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQzVCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO1lBRXZFLElBQUksSUFBSSxFQUFFO2dCQUNSLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3JDLElBQUksT0FBTztvQkFBRSxPQUFPLE1BQU0sQ0FBQztnQkFFM0IsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7Z0JBQ25DLElBQUksSUFBSSxFQUFFO29CQUNSLE1BQU0sUUFBUSxHQUFHO3dCQUNmLElBQUk7d0JBQ0osU0FBUzt3QkFDVCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFO3dCQUN2QixZQUFZLEVBQUUsR0FBRyxFQUFFLENBQ2pCLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7NEJBQ25CO2dDQUNFLElBQUksRUFBRSxFQUFFO2dDQUNSLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTztnQ0FDcEIsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLFNBQWtDLENBQUM7NkJBQ3ZEO3lCQUNGLENBQUM7cUJBQ0wsQ0FBQztvQkFFRixNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFpQixDQUFDLENBQUM7b0JBQ3BDLE9BQU8sTUFBTSxDQUFDO2lCQUNmO2FBQ0Y7WUFFRCxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUU7Z0JBQ2hCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO2dCQUNqRCxNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDO2dCQUVqRSxJQUFJLEtBQUssRUFBRTtvQkFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRTt3QkFDcEIsS0FBSyxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7cUJBQ3RCO29CQUVELEtBQUssQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO2lCQUM3QjtxQkFBTTtvQkFDTCxPQUFPLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDaEIsSUFBSTt3QkFDSixTQUFTO3dCQUNULE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUU7d0JBQ3ZCLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FDakIsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQzs0QkFDbkI7Z0NBQ0UsSUFBSSxFQUFFLEVBQUU7Z0NBQ1IsU0FBUyxFQUFFLENBQUMsQ0FBQyxPQUFPO2dDQUNwQixHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsU0FBa0MsQ0FBQzs2QkFDdkQ7eUJBQ0YsQ0FBQztxQkFDTCxDQUFDLENBQUM7aUJBQ0o7Z0JBRUQsT0FBTyxDQUNMLEtBQUs7b0JBQ0osT0FBTyxFQUFFLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBVyxDQUNwRSxDQUFDO2FBQ0g7WUFFRCxJQUFJLElBQUksRUFBRTtnQkFDUixNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQzFCLElBQUk7b0JBQ0osU0FBUztvQkFDVCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFO29CQUN2QixZQUFZLEVBQUUsR0FBRyxFQUFFLENBQ2pCLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7d0JBQ25COzRCQUNFLElBQUksRUFBRSxFQUFFOzRCQUNSLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTzs0QkFDcEIsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLFNBQWtDLENBQUM7eUJBQ3ZEO3FCQUNGLENBQUM7aUJBQ0wsQ0FBQyxDQUFDO2FBQ0o7WUFFRCxJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUU7Z0JBQ3BCLE1BQU0sQ0FBQyxhQUFhLEdBQUcsR0FBRyxFQUFFLENBQzFCLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFjLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDdkQsTUFBTSxDQUFDLFlBQVksR0FBRyxHQUFHLEVBQUUsQ0FDekIsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQWMsRUFBRSxFQUFFO29CQUN2QyxPQUFPO3dCQUNMOzRCQUNFLElBQUksRUFBRSxFQUFFOzRCQUNSLFFBQVEsRUFBRSxNQUFNLENBQUMsU0FBUzs0QkFDMUIsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLFNBQWtDLENBQUM7eUJBQ3ZEO3FCQUNGLENBQUM7Z0JBQ0osQ0FBQyxDQUFDLENBQUM7YUFDTjtZQUVELE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsRUFBRSxFQUF1RSxDQUFDLENBQUM7UUFFNUUsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxFQUNELEVBQUUsQ0FDSCxDQUFDO0lBRUYsT0FBTyxZQUFZLENBQUM7QUFDdEIsQ0FBQztBQUVELE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBWSxDQUFDLEdBQUcsU0FBUyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsR0FBRyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSB0eXBlcz1cInZpdGUvY2xpZW50XCIgLz5cblxuaW1wb3J0IHR5cGUgeyBSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7IFJvdXRlRXhwb3J0LCBSb3V0ZU1ldGEgfSBmcm9tICcuL21vZGVscyc7XG5pbXBvcnQgeyB0b1JvdXRlQ29uZmlnIH0gZnJvbSAnLi9yb3V0ZS1jb25maWcnO1xuaW1wb3J0IHsgdG9NYXJrZG93bk1vZHVsZSB9IGZyb20gJy4vbWFya2Rvd24taGVscGVycyc7XG5cbmNvbnN0IEZJTEVTID0gaW1wb3J0Lm1ldGEuZ2xvYjxSb3V0ZUV4cG9ydD4oW1xuICAnL2FwcC9yb3V0ZXMvKiovKi50cycsXG4gICcvc3JjL2FwcC9yb3V0ZXMvKiovKi50cycsXG4gICcvc3JjL2FwcC9wYWdlcy8qKi8qLnBhZ2UudHMnLFxuXSk7XG5cbmNvbnN0IENPTlRFTlRfRklMRVMgPSBpbXBvcnQubWV0YS5nbG9iPHN0cmluZz4oXG4gIFsnL3NyYy9hcHAvcm91dGVzLyoqLyoubWQnLCAnL3NyYy9hcHAvcGFnZXMvKiovKi5tZCddLFxuICB7XG4gICAgYXM6ICdyYXcnLFxuICB9XG4pO1xuXG4vKipcbiAqIEZ1bmN0aW9uIHVzZWQgdG8gcGFyc2UgbGlzdCBvZiBmaWxlcyBhbmQgcmV0dXJuXG4gKiBjb25maWd1cmF0aW9uIG9mIHJvdXRlcy5cbiAqXG4gKiBAcGFyYW0gZmlsZXNcbiAqIEByZXR1cm5zIEFycmF5IG9mIHJvdXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Um91dGVzKFxuICBmaWxlczogUmVjb3JkPHN0cmluZywgKCkgPT4gUHJvbWlzZTxSb3V0ZUV4cG9ydCB8IHN0cmluZz4+XG4pIHtcbiAgY29uc3QgUk9VVEVTID0gT2JqZWN0LmtleXMoZmlsZXMpLnNvcnQoKGEsIGIpID0+IGEubGVuZ3RoIC0gYi5sZW5ndGgpO1xuXG4gIGNvbnN0IHJvdXRlQ29uZmlncyA9IFJPVVRFUy5yZWR1Y2U8Um91dGVbXT4oXG4gICAgKHJvdXRlczogUm91dGVbXSwga2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IG1vZHVsZTogKCkgPT4gUHJvbWlzZTxSb3V0ZUV4cG9ydD4gPSBrZXkuZW5kc1dpdGgoJy5tZCcpXG4gICAgICAgID8gdG9NYXJrZG93bk1vZHVsZShmaWxlc1trZXldIGFzICgpID0+IFByb21pc2U8c3RyaW5nPilcbiAgICAgICAgOiAoZmlsZXNba2V5XSBhcyAoKSA9PiBQcm9taXNlPFJvdXRlRXhwb3J0Pik7XG5cbiAgICAgIGNvbnN0IHNlZ21lbnRzID0ga2V5XG4gICAgICAgIC5yZXBsYWNlKFxuICAgICAgICAgIC9eXFwvKC4qPylcXC9yb3V0ZXN8XlxcLyguKj8pXFwvcGFnZXN8XFwvYXBwXFwvcm91dGVzfFxcLnBhZ2V8XFwuKGpzfHRzfG1kKSQvZyxcbiAgICAgICAgICAnJ1xuICAgICAgICApXG4gICAgICAgIC5yZXBsYWNlKC9cXFtcXC57M30uK1xcXS8sICcqKicpXG4gICAgICAgIC5yZXBsYWNlKC9cXFsoW15cXF1dKylcXF0vZywgJzokMScpXG4gICAgICAgIC5zcGxpdCgnLycpXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG5cbiAgICAgIHNlZ21lbnRzLnJlZHVjZSgocGFyZW50LCBzZWdtZW50LCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBwYXRoID0gc2VnbWVudFxuICAgICAgICAgIC5yZXBsYWNlKC9pbmRleHxeXFwoLio/XFwpJC9nLCAnJylcbiAgICAgICAgICAucmVwbGFjZSgvXFwuL2csICcvJyk7XG4gICAgICAgIGNvbnN0IGlzSW5kZXggPSAhcGF0aDtcbiAgICAgICAgY29uc3QgaXNDYXRjaGFsbCA9IHBhdGggPT09ICcqKic7XG4gICAgICAgIGNvbnN0IHBhdGhNYXRjaCA9IGlzSW5kZXggPyAnZnVsbCcgOiAncHJlZml4JztcbiAgICAgICAgY29uc3Qgcm9vdCA9IGluZGV4ID09PSAwO1xuICAgICAgICBjb25zdCBsZWFmID0gaW5kZXggPT09IHNlZ21lbnRzLmxlbmd0aCAtIDEgJiYgc2VnbWVudHMubGVuZ3RoID4gMTtcbiAgICAgICAgY29uc3Qgbm9kZSA9ICFyb290ICYmICFsZWFmO1xuICAgICAgICBjb25zdCBpbnNlcnQgPSAvXlxcd3xcXC8vLnRlc3QocGF0aCkgJiYgIWlzQ2F0Y2hhbGwgPyAndW5zaGlmdCcgOiAncHVzaCc7XG5cbiAgICAgICAgaWYgKHJvb3QpIHtcbiAgICAgICAgICBjb25zdCBkeW5hbWljID0gcGF0aC5zdGFydHNXaXRoKCc6Jyk7XG4gICAgICAgICAgaWYgKGR5bmFtaWMpIHJldHVybiBwYXJlbnQ7XG5cbiAgICAgICAgICBjb25zdCBsYXN0ID0gc2VnbWVudHMubGVuZ3RoID09PSAxO1xuICAgICAgICAgIGlmIChsYXN0KSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSb3V0ZSA9IHtcbiAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgcGF0aE1hdGNoLFxuICAgICAgICAgICAgICBfbW9kdWxlOiAoKSA9PiBtb2R1bGUoKSxcbiAgICAgICAgICAgICAgbG9hZENoaWxkcmVuOiAoKSA9PlxuICAgICAgICAgICAgICAgIG1vZHVsZSgpLnRoZW4oKG0pID0+IFtcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudDogbS5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICAuLi50b1JvdXRlQ29uZmlnKG0ucm91dGVNZXRhIGFzIFJvdXRlTWV0YSB8IHVuZGVmaW5lZCksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcm91dGVzPy5baW5zZXJ0XShuZXdSb3V0ZSBhcyBSb3V0ZSk7XG4gICAgICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyb290IHx8IG5vZGUpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50ID0gcm9vdCA/IHJvdXRlcyA6IHBhcmVudC5fY2hpbGRyZW47XG4gICAgICAgICAgY29uc3QgZm91bmQgPSBjdXJyZW50Py5maW5kKChyb3V0ZTogYW55KSA9PiByb3V0ZS5wYXRoID09PSBwYXRoKTtcblxuICAgICAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAgICAgaWYgKCFmb3VuZC5fY2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgZm91bmQuX2NoaWxkcmVuID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvdW5kLnBhdGhNYXRjaCA9IHBhdGhNYXRjaDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudD8uW2luc2VydF0oe1xuICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICBwYXRoTWF0Y2gsXG4gICAgICAgICAgICAgIF9tb2R1bGU6ICgpID0+IG1vZHVsZSgpLFxuICAgICAgICAgICAgICBsb2FkQ2hpbGRyZW46ICgpID0+XG4gICAgICAgICAgICAgICAgbW9kdWxlKCkudGhlbigobSkgPT4gW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBwYXRoOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50OiBtLmRlZmF1bHQsXG4gICAgICAgICAgICAgICAgICAgIC4uLnRvUm91dGVDb25maWcobS5yb3V0ZU1ldGEgYXMgUm91dGVNZXRhIHwgdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgZm91bmQgfHxcbiAgICAgICAgICAgIChjdXJyZW50Py5baW5zZXJ0ID09PSAndW5zaGlmdCcgPyAwIDogY3VycmVudC5sZW5ndGggLSAxXSBhcyBSb3V0ZSlcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxlYWYpIHtcbiAgICAgICAgICBwYXJlbnQ/Ll9jaGlsZHJlbj8uW2luc2VydF0oe1xuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHBhdGhNYXRjaCxcbiAgICAgICAgICAgIF9tb2R1bGU6ICgpID0+IG1vZHVsZSgpLFxuICAgICAgICAgICAgbG9hZENoaWxkcmVuOiAoKSA9PlxuICAgICAgICAgICAgICBtb2R1bGUoKS50aGVuKChtKSA9PiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgICAgICAgICBjb21wb25lbnQ6IG0uZGVmYXVsdCxcbiAgICAgICAgICAgICAgICAgIC4uLnRvUm91dGVDb25maWcobS5yb3V0ZU1ldGEgYXMgUm91dGVNZXRhIHwgdW5kZWZpbmVkKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJlbnQuX2NoaWxkcmVuKSB7XG4gICAgICAgICAgcGFyZW50LmxvYWRDb21wb25lbnQgPSAoKSA9PlxuICAgICAgICAgICAgcGFyZW50Ll9tb2R1bGUoKS50aGVuKChtOiBSb3V0ZUV4cG9ydCkgPT4gbS5kZWZhdWx0KTtcbiAgICAgICAgICBwYXJlbnQubG9hZENoaWxkcmVuID0gKCkgPT5cbiAgICAgICAgICAgIHBhcmVudC5fbW9kdWxlKCkudGhlbigobTogUm91dGVFeHBvcnQpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBwYXRoOiAnJyxcbiAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBwYXJlbnQuX2NoaWxkcmVuLFxuICAgICAgICAgICAgICAgICAgLi4udG9Sb3V0ZUNvbmZpZyhtLnJvdXRlTWV0YSBhcyBSb3V0ZU1ldGEgfCB1bmRlZmluZWQpLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICB9LCB7fSBhcyBSb3V0ZSAmIHsgX21vZHVsZTogKCkgPT4gUHJvbWlzZTxSb3V0ZUV4cG9ydD47IF9jaGlsZHJlbjogYW55W10gfSk7XG5cbiAgICAgIHJldHVybiByb3V0ZXM7XG4gICAgfSxcbiAgICBbXVxuICApO1xuXG4gIHJldHVybiByb3V0ZUNvbmZpZ3M7XG59XG5cbmV4cG9ydCBjb25zdCByb3V0ZXM6IFJvdXRlW10gPSBbLi4uZ2V0Um91dGVzKHsgLi4uRklMRVMsIC4uLkNPTlRFTlRfRklMRVMgfSldO1xuIl19
@@ -1,8 +1,96 @@
1
- import { inject } from '@angular/core';
2
- import { Router, ActivatedRoute, provideRouter } from '@angular/router';
1
+ import { __rest } from 'tslib';
2
+ import { inject, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER } from '@angular/core';
3
+ import { Meta } from '@angular/platform-browser';
4
+ import { Router, NavigationEnd, ActivatedRoute, provideRouter } from '@angular/router';
5
+ import { filter } from 'rxjs/operators';
6
+
7
+ const ROUTE_META_TAGS_KEY = Symbol('@analogjs/router Route Meta Tags Key');
8
+ const CHARSET_KEY = 'charset';
9
+ const HTTP_EQUIV_KEY = 'httpEquiv';
10
+ // httpEquiv selector key needs to be in kebab case format
11
+ const HTTP_EQUIV_SELECTOR_KEY = 'http-equiv';
12
+ const NAME_KEY = 'name';
13
+ const PROPERTY_KEY = 'property';
14
+ const CONTENT_KEY = 'content';
15
+ function updateMetaTagsOnRouteChange() {
16
+ const router = inject(Router);
17
+ const metaService = inject(Meta);
18
+ router.events
19
+ .pipe(filter((event) => event instanceof NavigationEnd))
20
+ .subscribe(() => {
21
+ const metaTagMap = getMetaTagMap(router.routerState.snapshot.root);
22
+ for (const metaTagSelector in metaTagMap) {
23
+ const metaTag = metaTagMap[metaTagSelector];
24
+ metaService.updateTag(metaTag, metaTagSelector);
25
+ }
26
+ });
27
+ }
28
+ function getMetaTagMap(route) {
29
+ var _a;
30
+ const metaTagMap = {};
31
+ let currentRoute = route;
32
+ while (currentRoute) {
33
+ const metaTags = (_a = currentRoute.data[ROUTE_META_TAGS_KEY]) !== null && _a !== void 0 ? _a : [];
34
+ for (const metaTag of metaTags) {
35
+ metaTagMap[getMetaTagSelector(metaTag)] = metaTag;
36
+ }
37
+ currentRoute = currentRoute.firstChild;
38
+ }
39
+ return metaTagMap;
40
+ }
41
+ function getMetaTagSelector(metaTag) {
42
+ if (metaTag.name) {
43
+ return `${NAME_KEY}="${metaTag.name}"`;
44
+ }
45
+ if (metaTag.property) {
46
+ return `${PROPERTY_KEY}="${metaTag.property}"`;
47
+ }
48
+ if (metaTag.httpEquiv) {
49
+ return `${HTTP_EQUIV_SELECTOR_KEY}="${metaTag.httpEquiv}"`;
50
+ }
51
+ return CHARSET_KEY;
52
+ }
53
+
54
+ function toRouteConfig(routeMeta) {
55
+ if (!routeMeta) {
56
+ return {};
57
+ }
58
+ if (isRedirectRouteMeta(routeMeta)) {
59
+ return routeMeta;
60
+ }
61
+ const { meta } = routeMeta, routeConfig = __rest(routeMeta, ["meta"]);
62
+ if (Array.isArray(meta)) {
63
+ routeConfig.data = Object.assign(Object.assign({}, routeConfig.data), { [ROUTE_META_TAGS_KEY]: meta });
64
+ }
65
+ else if (typeof meta === 'function') {
66
+ routeConfig.resolve = Object.assign(Object.assign({}, routeConfig.resolve), { [ROUTE_META_TAGS_KEY]: meta });
67
+ }
68
+ return routeConfig;
69
+ }
70
+ function isRedirectRouteMeta(routeMeta) {
71
+ return !!routeMeta.redirectTo;
72
+ }
73
+
74
+ function toMarkdownModule(markdownFileFactory) {
75
+ return () => Promise.all([import('@analogjs/content'), markdownFileFactory()]).then(([{ parseRawContentFile, MarkdownComponent }, markdownFile]) => {
76
+ const { content, attributes } = parseRawContentFile(markdownFile);
77
+ const { title, meta } = attributes;
78
+ return {
79
+ default: MarkdownComponent,
80
+ routeMeta: { data: { _analogContent: content }, title, meta },
81
+ };
82
+ });
83
+ }
3
84
 
4
85
  /// <reference types="vite/client" />
5
- const FILES = import.meta.glob(['/app/routes/**/*.ts']);
86
+ const FILES = import.meta.glob([
87
+ '/app/routes/**/*.ts',
88
+ '/src/app/routes/**/*.ts',
89
+ '/src/app/pages/**/*.page.ts',
90
+ ]);
91
+ const CONTENT_FILES = import.meta.glob(['/src/app/routes/**/*.md', '/src/app/pages/**/*.md'], {
92
+ as: 'raw',
93
+ });
6
94
  /**
7
95
  * Function used to parse list of files and return
8
96
  * configuration of routes.
@@ -13,16 +101,20 @@ const FILES = import.meta.glob(['/app/routes/**/*.ts']);
13
101
  function getRoutes(files) {
14
102
  const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);
15
103
  const routeConfigs = ROUTES.reduce((routes, key) => {
16
- const module = files[key];
104
+ const module = key.endsWith('.md')
105
+ ? toMarkdownModule(files[key])
106
+ : files[key];
17
107
  const segments = key
18
- .replace(/\/app\/routes|\.(js|ts)$/g, '')
108
+ .replace(/^\/(.*?)\/routes|^\/(.*?)\/pages|\/app\/routes|\.page|\.(js|ts|md)$/g, '')
19
109
  .replace(/\[\.{3}.+\]/, '**')
20
110
  .replace(/\[([^\]]+)\]/g, ':$1')
21
111
  .split('/')
22
112
  .filter(Boolean);
23
113
  segments.reduce((parent, segment, index) => {
24
114
  var _a;
25
- const path = segment.replace(/index/g, '').replace('.', '/');
115
+ const path = segment
116
+ .replace(/index|^\(.*?\)$/g, '')
117
+ .replace(/\./g, '/');
26
118
  const isIndex = !path;
27
119
  const isCatchall = path === '**';
28
120
  const pathMatch = isIndex ? 'full' : 'prefix';
@@ -41,7 +133,7 @@ function getRoutes(files) {
41
133
  pathMatch,
42
134
  _module: () => module(),
43
135
  loadChildren: () => module().then((m) => [
44
- Object.assign({ path: '', component: m.default }, m.routeMeta),
136
+ Object.assign({ path: '', component: m.default }, toRouteConfig(m.routeMeta)),
45
137
  ]),
46
138
  };
47
139
  routes === null || routes === void 0 ? void 0 : routes[insert](newRoute);
@@ -63,7 +155,7 @@ function getRoutes(files) {
63
155
  pathMatch,
64
156
  _module: () => module(),
65
157
  loadChildren: () => module().then((m) => [
66
- Object.assign({ path: '', component: m.default }, m.routeMeta),
158
+ Object.assign({ path: '', component: m.default }, toRouteConfig(m.routeMeta)),
67
159
  ]),
68
160
  });
69
161
  }
@@ -76,7 +168,7 @@ function getRoutes(files) {
76
168
  pathMatch,
77
169
  _module: () => module(),
78
170
  loadChildren: () => module().then((m) => [
79
- Object.assign({ path: '', component: m.default }, m.routeMeta),
171
+ Object.assign({ path: '', component: m.default }, toRouteConfig(m.routeMeta)),
80
172
  ]),
81
173
  });
82
174
  }
@@ -84,7 +176,7 @@ function getRoutes(files) {
84
176
  parent.loadComponent = () => parent._module().then((m) => m.default);
85
177
  parent.loadChildren = () => parent._module().then((m) => {
86
178
  return [
87
- Object.assign({ path: '', children: parent._children }, m.routeMeta),
179
+ Object.assign({ path: '', children: parent._children }, toRouteConfig(m.routeMeta)),
88
180
  ];
89
181
  });
90
182
  }
@@ -94,9 +186,12 @@ function getRoutes(files) {
94
186
  }, []);
95
187
  return routeConfigs;
96
188
  }
97
- const routes = [...getRoutes(FILES)];
189
+ const routes = [...getRoutes(Object.assign(Object.assign({}, FILES), CONTENT_FILES))];
98
190
 
99
191
  /**
192
+ * @deprecated Use `RouteMeta` type instead.
193
+ * For more info see: https://github.com/analogjs/analog/issues/223
194
+ *
100
195
  * Defines additional route config metadata. This
101
196
  * object is merged into the route config with
102
197
  * the predefined file-based route.
@@ -149,9 +244,18 @@ const injectActivatedRoute = () => {
149
244
  * @param features
150
245
  * @returns Providers and features to configure the router with routes
151
246
  */
152
- const provideFileRouter = (...features) => {
153
- return provideRouter(routes, ...features);
154
- };
247
+ function provideFileRouter(...features) {
248
+ return makeEnvironmentProviders([
249
+ // TODO: remove type casting after Angular >=15.1.1 upgrade
250
+ // https://github.com/angular/angular/pull/48720
251
+ provideRouter(routes, ...features).ɵproviders,
252
+ {
253
+ provide: ENVIRONMENT_INITIALIZER,
254
+ multi: true,
255
+ useValue: () => updateMetaTagsOnRouteChange(),
256
+ },
257
+ ]);
258
+ }
155
259
 
156
260
  /**
157
261
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"analogjs-router.mjs","sources":["../../../../packages/router/src/lib/routes.ts","../../../../packages/router/src/lib/define-route.ts","../../../../packages/router/src/lib/provide-file-routes.ts","../../../../packages/router/src/analogjs-router.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport type { Type } from '@angular/core';\nimport type { Route } from '@angular/router';\nimport { defineRouteMeta } from './define-route';\n\nexport type RouteExport = {\n default: Type<unknown>;\n routeMeta?: ReturnType<typeof defineRouteMeta>;\n};\n\nconst FILES = import.meta.glob<RouteExport>(['/app/routes/**/*.ts']);\n\n/**\n * Function used to parse list of files and return\n * configuration of routes.\n *\n * @param files\n * @returns Array of routes\n */\nexport function getRoutes(files: Record<string, () => Promise<RouteExport>>) {\n const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);\n\n const routeConfigs = ROUTES.reduce<Route[]>(\n (routes: Route[], key: string) => {\n const module = files[key];\n\n const segments = key\n .replace(/\\/app\\/routes|\\.(js|ts)$/g, '')\n .replace(/\\[\\.{3}.+\\]/, '**')\n .replace(/\\[([^\\]]+)\\]/g, ':$1')\n .split('/')\n .filter(Boolean);\n\n segments.reduce((parent, segment, index) => {\n const path = segment.replace(/index/g, '').replace('.', '/');\n const isIndex = !path;\n const isCatchall = path === '**';\n const pathMatch = isIndex ? 'full' : 'prefix';\n const root = index === 0;\n const leaf = index === segments.length - 1 && segments.length > 1;\n const node = !root && !leaf;\n const insert = /^\\w|\\//.test(path) && !isCatchall ? 'unshift' : 'push';\n\n if (root) {\n const dynamic = path.startsWith(':');\n if (dynamic) return parent;\n\n const last = segments.length === 1;\n if (last) {\n const newRoute = {\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...m.routeMeta,\n },\n ]),\n };\n\n routes?.[insert](newRoute as Route);\n return parent;\n }\n }\n\n if (root || node) {\n const current = root ? routes : parent._children;\n const found = current?.find((route: any) => route.path === path);\n\n if (found) {\n if (!found._children) {\n found._children = [];\n }\n\n found.pathMatch = pathMatch;\n } else {\n current?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...m.routeMeta,\n },\n ]),\n });\n }\n\n return (\n found ||\n (current?.[insert === 'unshift' ? 0 : current.length - 1] as Route)\n );\n }\n\n if (leaf) {\n parent?._children?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...m.routeMeta,\n },\n ]),\n });\n }\n\n if (parent._children) {\n parent.loadComponent = () =>\n parent._module().then((m: RouteExport) => m.default);\n parent.loadChildren = () =>\n parent._module().then((m: RouteExport) => {\n return [\n {\n path: '',\n children: parent._children,\n ...m.routeMeta,\n },\n ];\n });\n }\n\n return parent;\n }, {} as Route & { _module: () => Promise<RouteExport>; _children: any[] });\n\n return routes;\n },\n []\n );\n\n return routeConfigs;\n}\n\nexport const routes: Route[] = [...getRoutes(FILES)];\n","import { inject } from '@angular/core';\nimport { Route as NgRoute, Router } from '@angular/router';\nimport { ActivatedRoute } from '@angular/router';\n\ntype RouteOmitted =\n | 'component'\n | 'loadComponent'\n | 'loadChildren'\n | 'path'\n | 'pathMatch';\n\ntype RestrictedRoute = Omit<NgRoute, RouteOmitted>;\n\n/**\n * Defines additional route config metadata. This\n * object is merged into the route config with\n * the predefined file-based route.\n *\n * @usageNotes\n *\n * ```\n * import { Component } from '@angular/core';\n * import { defineRouteMeta } from '@analogjs/router';\n *\n * export const routeMeta = defineRouteMeta({\n * title: 'Welcome'\n * });\n *\n * @Component({\n * template: `Home`,\n * standalone: true,\n * })\n * export default class HomeComponent {}\n * ```\n *\n * @param route\n * @returns\n */\nexport const defineRouteMeta = (route: RestrictedRoute) => {\n return route;\n};\n\n/**\n * Returns the instance of Angular Router\n *\n * @returns The router\n */\nexport const injectRouter = () => {\n return inject(Router);\n};\n\n/**\n * Returns the instance of the Activate Route for the component\n *\n * @returns The activated route\n */\nexport const injectActivatedRoute = () => {\n return inject(ActivatedRoute);\n};\n","import { provideRouter, RouterFeatures } from '@angular/router';\nimport { routes } from './routes';\n\n/**\n * Sets up providers for the Angular router, and registers\n * file-based routes. Additional features can be provided\n * to further configure the behavior of the router.\n *\n * @param features\n * @returns Providers and features to configure the router with routes\n */\nexport const provideFileRouter = (...features: RouterFeatures[]) => {\n return provideRouter(routes, ...features);\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analogjs-router.mjs","sources":["../../../../packages/router/src/lib/meta-tags.ts","../../../../packages/router/src/lib/route-config.ts","../../../../packages/router/src/lib/markdown-helpers.ts","../../../../packages/router/src/lib/routes.ts","../../../../packages/router/src/lib/define-route.ts","../../../../packages/router/src/lib/provide-file-router.ts","../../../../packages/router/src/analogjs-router.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { Meta, MetaDefinition as NgMetaTag } from '@angular/platform-browser';\nimport { ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs/operators';\n\nexport const ROUTE_META_TAGS_KEY = Symbol(\n '@analogjs/router Route Meta Tags Key'\n);\n\nconst CHARSET_KEY = 'charset';\nconst HTTP_EQUIV_KEY = 'httpEquiv';\n// httpEquiv selector key needs to be in kebab case format\nconst HTTP_EQUIV_SELECTOR_KEY = 'http-equiv';\nconst NAME_KEY = 'name';\nconst PROPERTY_KEY = 'property';\nconst CONTENT_KEY = 'content';\n\nexport type MetaTag =\n | (CharsetMetaTag & ExcludeRestMetaTagKeys<typeof CHARSET_KEY>)\n | (HttpEquivMetaTag & ExcludeRestMetaTagKeys<typeof HTTP_EQUIV_KEY>)\n | (NameMetaTag & ExcludeRestMetaTagKeys<typeof NAME_KEY>)\n | (PropertyMetaTag & ExcludeRestMetaTagKeys<typeof PROPERTY_KEY>);\n\ntype CharsetMetaTag = { [CHARSET_KEY]: string };\ntype HttpEquivMetaTag = { [HTTP_EQUIV_KEY]: string; [CONTENT_KEY]: string };\ntype NameMetaTag = { [NAME_KEY]: string; [CONTENT_KEY]: string };\ntype PropertyMetaTag = { [PROPERTY_KEY]: string; [CONTENT_KEY]: string };\n\ntype MetaTagKey =\n | typeof CHARSET_KEY\n | typeof HTTP_EQUIV_KEY\n | typeof NAME_KEY\n | typeof PROPERTY_KEY;\ntype ExcludeRestMetaTagKeys<Key extends MetaTagKey> = {\n [K in Exclude<MetaTagKey, Key>]?: never;\n};\n\ntype MetaTagSelector =\n | typeof CHARSET_KEY\n | `${\n | typeof HTTP_EQUIV_SELECTOR_KEY\n | typeof NAME_KEY\n | typeof PROPERTY_KEY}=\"${string}\"`;\ntype MetaTagMap = Record<MetaTagSelector, MetaTag>;\n\nexport function updateMetaTagsOnRouteChange(): void {\n const router = inject(Router);\n const metaService = inject(Meta);\n\n router.events\n .pipe(filter((event) => event instanceof NavigationEnd))\n .subscribe(() => {\n const metaTagMap = getMetaTagMap(router.routerState.snapshot.root);\n\n for (const metaTagSelector in metaTagMap) {\n const metaTag = metaTagMap[\n metaTagSelector as MetaTagSelector\n ] as NgMetaTag;\n metaService.updateTag(metaTag, metaTagSelector);\n }\n });\n}\n\nfunction getMetaTagMap(route: ActivatedRouteSnapshot): MetaTagMap {\n const metaTagMap = {} as MetaTagMap;\n let currentRoute: ActivatedRouteSnapshot | null = route;\n\n while (currentRoute) {\n const metaTags: MetaTag[] = currentRoute.data[ROUTE_META_TAGS_KEY] ?? [];\n for (const metaTag of metaTags) {\n metaTagMap[getMetaTagSelector(metaTag)] = metaTag;\n }\n\n currentRoute = currentRoute.firstChild;\n }\n\n return metaTagMap;\n}\n\nfunction getMetaTagSelector(metaTag: MetaTag): MetaTagSelector {\n if (metaTag.name) {\n return `${NAME_KEY}=\"${metaTag.name}\"`;\n }\n\n if (metaTag.property) {\n return `${PROPERTY_KEY}=\"${metaTag.property}\"`;\n }\n\n if (metaTag.httpEquiv) {\n return `${HTTP_EQUIV_SELECTOR_KEY}=\"${metaTag.httpEquiv}\"`;\n }\n\n return CHARSET_KEY;\n}\n","import { RedirectRouteMeta, RouteConfig, RouteMeta } from './models';\nimport { ROUTE_META_TAGS_KEY } from './meta-tags';\n\nexport function toRouteConfig(routeMeta: RouteMeta | undefined): RouteConfig {\n if (!routeMeta) {\n return {};\n }\n\n if (isRedirectRouteMeta(routeMeta)) {\n return routeMeta;\n }\n\n const { meta, ...routeConfig } = routeMeta;\n\n if (Array.isArray(meta)) {\n routeConfig.data = { ...routeConfig.data, [ROUTE_META_TAGS_KEY]: meta };\n } else if (typeof meta === 'function') {\n routeConfig.resolve = {\n ...routeConfig.resolve,\n [ROUTE_META_TAGS_KEY]: meta,\n };\n }\n\n return routeConfig;\n}\n\nfunction isRedirectRouteMeta(\n routeMeta: RouteMeta\n): routeMeta is RedirectRouteMeta {\n return !!routeMeta.redirectTo;\n}\n","import { RouteExport } from './models';\n\nexport function toMarkdownModule(\n markdownFileFactory: () => Promise<string>\n): () => Promise<RouteExport> {\n return () =>\n Promise.all([import('@analogjs/content'), markdownFileFactory()]).then(\n ([{ parseRawContentFile, MarkdownComponent }, markdownFile]) => {\n const { content, attributes } = parseRawContentFile(markdownFile);\n const { title, meta } = attributes;\n\n return {\n default: MarkdownComponent,\n routeMeta: { data: { _analogContent: content }, title, meta },\n };\n }\n );\n}\n","/// <reference types=\"vite/client\" />\n\nimport type { Route } from '@angular/router';\n\nimport { RouteExport, RouteMeta } from './models';\nimport { toRouteConfig } from './route-config';\nimport { toMarkdownModule } from './markdown-helpers';\n\nconst FILES = import.meta.glob<RouteExport>([\n '/app/routes/**/*.ts',\n '/src/app/routes/**/*.ts',\n '/src/app/pages/**/*.page.ts',\n]);\n\nconst CONTENT_FILES = import.meta.glob<string>(\n ['/src/app/routes/**/*.md', '/src/app/pages/**/*.md'],\n {\n as: 'raw',\n }\n);\n\n/**\n * Function used to parse list of files and return\n * configuration of routes.\n *\n * @param files\n * @returns Array of routes\n */\nexport function getRoutes(\n files: Record<string, () => Promise<RouteExport | string>>\n) {\n const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);\n\n const routeConfigs = ROUTES.reduce<Route[]>(\n (routes: Route[], key: string) => {\n const module: () => Promise<RouteExport> = key.endsWith('.md')\n ? toMarkdownModule(files[key] as () => Promise<string>)\n : (files[key] as () => Promise<RouteExport>);\n\n const segments = key\n .replace(\n /^\\/(.*?)\\/routes|^\\/(.*?)\\/pages|\\/app\\/routes|\\.page|\\.(js|ts|md)$/g,\n ''\n )\n .replace(/\\[\\.{3}.+\\]/, '**')\n .replace(/\\[([^\\]]+)\\]/g, ':$1')\n .split('/')\n .filter(Boolean);\n\n segments.reduce((parent, segment, index) => {\n const path = segment\n .replace(/index|^\\(.*?\\)$/g, '')\n .replace(/\\./g, '/');\n const isIndex = !path;\n const isCatchall = path === '**';\n const pathMatch = isIndex ? 'full' : 'prefix';\n const root = index === 0;\n const leaf = index === segments.length - 1 && segments.length > 1;\n const node = !root && !leaf;\n const insert = /^\\w|\\//.test(path) && !isCatchall ? 'unshift' : 'push';\n\n if (root) {\n const dynamic = path.startsWith(':');\n if (dynamic) return parent;\n\n const last = segments.length === 1;\n if (last) {\n const newRoute = {\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ]),\n };\n\n routes?.[insert](newRoute as Route);\n return parent;\n }\n }\n\n if (root || node) {\n const current = root ? routes : parent._children;\n const found = current?.find((route: any) => route.path === path);\n\n if (found) {\n if (!found._children) {\n found._children = [];\n }\n\n found.pathMatch = pathMatch;\n } else {\n current?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ]),\n });\n }\n\n return (\n found ||\n (current?.[insert === 'unshift' ? 0 : current.length - 1] as Route)\n );\n }\n\n if (leaf) {\n parent?._children?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ]),\n });\n }\n\n if (parent._children) {\n parent.loadComponent = () =>\n parent._module().then((m: RouteExport) => m.default);\n parent.loadChildren = () =>\n parent._module().then((m: RouteExport) => {\n return [\n {\n path: '',\n children: parent._children,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ];\n });\n }\n\n return parent;\n }, {} as Route & { _module: () => Promise<RouteExport>; _children: any[] });\n\n return routes;\n },\n []\n );\n\n return routeConfigs;\n}\n\nexport const routes: Route[] = [...getRoutes({ ...FILES, ...CONTENT_FILES })];\n","import { inject } from '@angular/core';\nimport { Route as NgRoute, Router } from '@angular/router';\nimport { ActivatedRoute } from '@angular/router';\n\ntype RouteOmitted =\n | 'component'\n | 'loadComponent'\n | 'loadChildren'\n | 'path'\n | 'pathMatch';\n\ntype RestrictedRoute = Omit<NgRoute, RouteOmitted>;\n\n/**\n * @deprecated Use `RouteMeta` type instead.\n * For more info see: https://github.com/analogjs/analog/issues/223\n *\n * Defines additional route config metadata. This\n * object is merged into the route config with\n * the predefined file-based route.\n *\n * @usageNotes\n *\n * ```\n * import { Component } from '@angular/core';\n * import { defineRouteMeta } from '@analogjs/router';\n *\n * export const routeMeta = defineRouteMeta({\n * title: 'Welcome'\n * });\n *\n * @Component({\n * template: `Home`,\n * standalone: true,\n * })\n * export default class HomeComponent {}\n * ```\n *\n * @param route\n * @returns\n */\nexport const defineRouteMeta = (route: RestrictedRoute) => {\n return route;\n};\n\n/**\n * Returns the instance of Angular Router\n *\n * @returns The router\n */\nexport const injectRouter = () => {\n return inject(Router);\n};\n\n/**\n * Returns the instance of the Activate Route for the component\n *\n * @returns The activated route\n */\nexport const injectActivatedRoute = () => {\n return inject(ActivatedRoute);\n};\n","import {\n ENVIRONMENT_INITIALIZER,\n EnvironmentProviders,\n makeEnvironmentProviders,\n Provider,\n} from '@angular/core';\nimport { provideRouter, RouterFeatures } from '@angular/router';\n\nimport { routes } from './routes';\nimport { updateMetaTagsOnRouteChange } from './meta-tags';\n\n/**\n * Sets up providers for the Angular router, and registers\n * file-based routes. Additional features can be provided\n * to further configure the behavior of the router.\n *\n * @param features\n * @returns Providers and features to configure the router with routes\n */\nexport function provideFileRouter(\n ...features: RouterFeatures[]\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n // TODO: remove type casting after Angular >=15.1.1 upgrade\n // https://github.com/angular/angular/pull/48720\n (\n provideRouter(routes, ...features) as unknown as {\n ɵproviders: Provider[];\n }\n ).ɵproviders,\n {\n provide: ENVIRONMENT_INITIALIZER,\n multi: true,\n useValue: () => updateMetaTagsOnRouteChange(),\n },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,8 +1,97 @@
1
- import { inject } from '@angular/core';
2
- import { Router, ActivatedRoute, provideRouter } from '@angular/router';
1
+ import { inject, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER } from '@angular/core';
2
+ import { Meta } from '@angular/platform-browser';
3
+ import { Router, NavigationEnd, ActivatedRoute, provideRouter } from '@angular/router';
4
+ import { filter } from 'rxjs/operators';
5
+
6
+ const ROUTE_META_TAGS_KEY = Symbol('@analogjs/router Route Meta Tags Key');
7
+ const CHARSET_KEY = 'charset';
8
+ const HTTP_EQUIV_KEY = 'httpEquiv';
9
+ // httpEquiv selector key needs to be in kebab case format
10
+ const HTTP_EQUIV_SELECTOR_KEY = 'http-equiv';
11
+ const NAME_KEY = 'name';
12
+ const PROPERTY_KEY = 'property';
13
+ const CONTENT_KEY = 'content';
14
+ function updateMetaTagsOnRouteChange() {
15
+ const router = inject(Router);
16
+ const metaService = inject(Meta);
17
+ router.events
18
+ .pipe(filter((event) => event instanceof NavigationEnd))
19
+ .subscribe(() => {
20
+ const metaTagMap = getMetaTagMap(router.routerState.snapshot.root);
21
+ for (const metaTagSelector in metaTagMap) {
22
+ const metaTag = metaTagMap[metaTagSelector];
23
+ metaService.updateTag(metaTag, metaTagSelector);
24
+ }
25
+ });
26
+ }
27
+ function getMetaTagMap(route) {
28
+ const metaTagMap = {};
29
+ let currentRoute = route;
30
+ while (currentRoute) {
31
+ const metaTags = currentRoute.data[ROUTE_META_TAGS_KEY] ?? [];
32
+ for (const metaTag of metaTags) {
33
+ metaTagMap[getMetaTagSelector(metaTag)] = metaTag;
34
+ }
35
+ currentRoute = currentRoute.firstChild;
36
+ }
37
+ return metaTagMap;
38
+ }
39
+ function getMetaTagSelector(metaTag) {
40
+ if (metaTag.name) {
41
+ return `${NAME_KEY}="${metaTag.name}"`;
42
+ }
43
+ if (metaTag.property) {
44
+ return `${PROPERTY_KEY}="${metaTag.property}"`;
45
+ }
46
+ if (metaTag.httpEquiv) {
47
+ return `${HTTP_EQUIV_SELECTOR_KEY}="${metaTag.httpEquiv}"`;
48
+ }
49
+ return CHARSET_KEY;
50
+ }
51
+
52
+ function toRouteConfig(routeMeta) {
53
+ if (!routeMeta) {
54
+ return {};
55
+ }
56
+ if (isRedirectRouteMeta(routeMeta)) {
57
+ return routeMeta;
58
+ }
59
+ const { meta, ...routeConfig } = routeMeta;
60
+ if (Array.isArray(meta)) {
61
+ routeConfig.data = { ...routeConfig.data, [ROUTE_META_TAGS_KEY]: meta };
62
+ }
63
+ else if (typeof meta === 'function') {
64
+ routeConfig.resolve = {
65
+ ...routeConfig.resolve,
66
+ [ROUTE_META_TAGS_KEY]: meta,
67
+ };
68
+ }
69
+ return routeConfig;
70
+ }
71
+ function isRedirectRouteMeta(routeMeta) {
72
+ return !!routeMeta.redirectTo;
73
+ }
74
+
75
+ function toMarkdownModule(markdownFileFactory) {
76
+ return () => Promise.all([import('@analogjs/content'), markdownFileFactory()]).then(([{ parseRawContentFile, MarkdownComponent }, markdownFile]) => {
77
+ const { content, attributes } = parseRawContentFile(markdownFile);
78
+ const { title, meta } = attributes;
79
+ return {
80
+ default: MarkdownComponent,
81
+ routeMeta: { data: { _analogContent: content }, title, meta },
82
+ };
83
+ });
84
+ }
3
85
 
4
86
  /// <reference types="vite/client" />
5
- const FILES = import.meta.glob(['/app/routes/**/*.ts']);
87
+ const FILES = import.meta.glob([
88
+ '/app/routes/**/*.ts',
89
+ '/src/app/routes/**/*.ts',
90
+ '/src/app/pages/**/*.page.ts',
91
+ ]);
92
+ const CONTENT_FILES = import.meta.glob(['/src/app/routes/**/*.md', '/src/app/pages/**/*.md'], {
93
+ as: 'raw',
94
+ });
6
95
  /**
7
96
  * Function used to parse list of files and return
8
97
  * configuration of routes.
@@ -13,15 +102,19 @@ const FILES = import.meta.glob(['/app/routes/**/*.ts']);
13
102
  function getRoutes(files) {
14
103
  const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);
15
104
  const routeConfigs = ROUTES.reduce((routes, key) => {
16
- const module = files[key];
105
+ const module = key.endsWith('.md')
106
+ ? toMarkdownModule(files[key])
107
+ : files[key];
17
108
  const segments = key
18
- .replace(/\/app\/routes|\.(js|ts)$/g, '')
109
+ .replace(/^\/(.*?)\/routes|^\/(.*?)\/pages|\/app\/routes|\.page|\.(js|ts|md)$/g, '')
19
110
  .replace(/\[\.{3}.+\]/, '**')
20
111
  .replace(/\[([^\]]+)\]/g, ':$1')
21
112
  .split('/')
22
113
  .filter(Boolean);
23
114
  segments.reduce((parent, segment, index) => {
24
- const path = segment.replace(/index/g, '').replace('.', '/');
115
+ const path = segment
116
+ .replace(/index|^\(.*?\)$/g, '')
117
+ .replace(/\./g, '/');
25
118
  const isIndex = !path;
26
119
  const isCatchall = path === '**';
27
120
  const pathMatch = isIndex ? 'full' : 'prefix';
@@ -43,7 +136,7 @@ function getRoutes(files) {
43
136
  {
44
137
  path: '',
45
138
  component: m.default,
46
- ...m.routeMeta,
139
+ ...toRouteConfig(m.routeMeta),
47
140
  },
48
141
  ]),
49
142
  };
@@ -69,7 +162,7 @@ function getRoutes(files) {
69
162
  {
70
163
  path: '',
71
164
  component: m.default,
72
- ...m.routeMeta,
165
+ ...toRouteConfig(m.routeMeta),
73
166
  },
74
167
  ]),
75
168
  });
@@ -86,7 +179,7 @@ function getRoutes(files) {
86
179
  {
87
180
  path: '',
88
181
  component: m.default,
89
- ...m.routeMeta,
182
+ ...toRouteConfig(m.routeMeta),
90
183
  },
91
184
  ]),
92
185
  });
@@ -98,7 +191,7 @@ function getRoutes(files) {
98
191
  {
99
192
  path: '',
100
193
  children: parent._children,
101
- ...m.routeMeta,
194
+ ...toRouteConfig(m.routeMeta),
102
195
  },
103
196
  ];
104
197
  });
@@ -109,9 +202,12 @@ function getRoutes(files) {
109
202
  }, []);
110
203
  return routeConfigs;
111
204
  }
112
- const routes = [...getRoutes(FILES)];
205
+ const routes = [...getRoutes({ ...FILES, ...CONTENT_FILES })];
113
206
 
114
207
  /**
208
+ * @deprecated Use `RouteMeta` type instead.
209
+ * For more info see: https://github.com/analogjs/analog/issues/223
210
+ *
115
211
  * Defines additional route config metadata. This
116
212
  * object is merged into the route config with
117
213
  * the predefined file-based route.
@@ -164,9 +260,18 @@ const injectActivatedRoute = () => {
164
260
  * @param features
165
261
  * @returns Providers and features to configure the router with routes
166
262
  */
167
- const provideFileRouter = (...features) => {
168
- return provideRouter(routes, ...features);
169
- };
263
+ function provideFileRouter(...features) {
264
+ return makeEnvironmentProviders([
265
+ // TODO: remove type casting after Angular >=15.1.1 upgrade
266
+ // https://github.com/angular/angular/pull/48720
267
+ provideRouter(routes, ...features).ɵproviders,
268
+ {
269
+ provide: ENVIRONMENT_INITIALIZER,
270
+ multi: true,
271
+ useValue: () => updateMetaTagsOnRouteChange(),
272
+ },
273
+ ]);
274
+ }
170
275
 
171
276
  /**
172
277
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"analogjs-router.mjs","sources":["../../../../packages/router/src/lib/routes.ts","../../../../packages/router/src/lib/define-route.ts","../../../../packages/router/src/lib/provide-file-routes.ts","../../../../packages/router/src/analogjs-router.ts"],"sourcesContent":["/// <reference types=\"vite/client\" />\n\nimport type { Type } from '@angular/core';\nimport type { Route } from '@angular/router';\nimport { defineRouteMeta } from './define-route';\n\nexport type RouteExport = {\n default: Type<unknown>;\n routeMeta?: ReturnType<typeof defineRouteMeta>;\n};\n\nconst FILES = import.meta.glob<RouteExport>(['/app/routes/**/*.ts']);\n\n/**\n * Function used to parse list of files and return\n * configuration of routes.\n *\n * @param files\n * @returns Array of routes\n */\nexport function getRoutes(files: Record<string, () => Promise<RouteExport>>) {\n const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);\n\n const routeConfigs = ROUTES.reduce<Route[]>(\n (routes: Route[], key: string) => {\n const module = files[key];\n\n const segments = key\n .replace(/\\/app\\/routes|\\.(js|ts)$/g, '')\n .replace(/\\[\\.{3}.+\\]/, '**')\n .replace(/\\[([^\\]]+)\\]/g, ':$1')\n .split('/')\n .filter(Boolean);\n\n segments.reduce((parent, segment, index) => {\n const path = segment.replace(/index/g, '').replace('.', '/');\n const isIndex = !path;\n const isCatchall = path === '**';\n const pathMatch = isIndex ? 'full' : 'prefix';\n const root = index === 0;\n const leaf = index === segments.length - 1 && segments.length > 1;\n const node = !root && !leaf;\n const insert = /^\\w|\\//.test(path) && !isCatchall ? 'unshift' : 'push';\n\n if (root) {\n const dynamic = path.startsWith(':');\n if (dynamic) return parent;\n\n const last = segments.length === 1;\n if (last) {\n const newRoute = {\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...m.routeMeta,\n },\n ]),\n };\n\n routes?.[insert](newRoute as Route);\n return parent;\n }\n }\n\n if (root || node) {\n const current = root ? routes : parent._children;\n const found = current?.find((route: any) => route.path === path);\n\n if (found) {\n if (!found._children) {\n found._children = [];\n }\n\n found.pathMatch = pathMatch;\n } else {\n current?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...m.routeMeta,\n },\n ]),\n });\n }\n\n return (\n found ||\n (current?.[insert === 'unshift' ? 0 : current.length - 1] as Route)\n );\n }\n\n if (leaf) {\n parent?._children?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...m.routeMeta,\n },\n ]),\n });\n }\n\n if (parent._children) {\n parent.loadComponent = () =>\n parent._module().then((m: RouteExport) => m.default);\n parent.loadChildren = () =>\n parent._module().then((m: RouteExport) => {\n return [\n {\n path: '',\n children: parent._children,\n ...m.routeMeta,\n },\n ];\n });\n }\n\n return parent;\n }, {} as Route & { _module: () => Promise<RouteExport>; _children: any[] });\n\n return routes;\n },\n []\n );\n\n return routeConfigs;\n}\n\nexport const routes: Route[] = [...getRoutes(FILES)];\n","import { inject } from '@angular/core';\nimport { Route as NgRoute, Router } from '@angular/router';\nimport { ActivatedRoute } from '@angular/router';\n\ntype RouteOmitted =\n | 'component'\n | 'loadComponent'\n | 'loadChildren'\n | 'path'\n | 'pathMatch';\n\ntype RestrictedRoute = Omit<NgRoute, RouteOmitted>;\n\n/**\n * Defines additional route config metadata. This\n * object is merged into the route config with\n * the predefined file-based route.\n *\n * @usageNotes\n *\n * ```\n * import { Component } from '@angular/core';\n * import { defineRouteMeta } from '@analogjs/router';\n *\n * export const routeMeta = defineRouteMeta({\n * title: 'Welcome'\n * });\n *\n * @Component({\n * template: `Home`,\n * standalone: true,\n * })\n * export default class HomeComponent {}\n * ```\n *\n * @param route\n * @returns\n */\nexport const defineRouteMeta = (route: RestrictedRoute) => {\n return route;\n};\n\n/**\n * Returns the instance of Angular Router\n *\n * @returns The router\n */\nexport const injectRouter = () => {\n return inject(Router);\n};\n\n/**\n * Returns the instance of the Activate Route for the component\n *\n * @returns The activated route\n */\nexport const injectActivatedRoute = () => {\n return inject(ActivatedRoute);\n};\n","import { provideRouter, RouterFeatures } from '@angular/router';\nimport { routes } from './routes';\n\n/**\n * Sets up providers for the Angular router, and registers\n * file-based routes. Additional features can be provided\n * to further configure the behavior of the router.\n *\n * @param features\n * @returns Providers and features to configure the router with routes\n */\nexport const provideFileRouter = (...features: RouterFeatures[]) => {\n return provideRouter(routes, ...features);\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analogjs-router.mjs","sources":["../../../../packages/router/src/lib/meta-tags.ts","../../../../packages/router/src/lib/route-config.ts","../../../../packages/router/src/lib/markdown-helpers.ts","../../../../packages/router/src/lib/routes.ts","../../../../packages/router/src/lib/define-route.ts","../../../../packages/router/src/lib/provide-file-router.ts","../../../../packages/router/src/analogjs-router.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport { Meta, MetaDefinition as NgMetaTag } from '@angular/platform-browser';\nimport { ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs/operators';\n\nexport const ROUTE_META_TAGS_KEY = Symbol(\n '@analogjs/router Route Meta Tags Key'\n);\n\nconst CHARSET_KEY = 'charset';\nconst HTTP_EQUIV_KEY = 'httpEquiv';\n// httpEquiv selector key needs to be in kebab case format\nconst HTTP_EQUIV_SELECTOR_KEY = 'http-equiv';\nconst NAME_KEY = 'name';\nconst PROPERTY_KEY = 'property';\nconst CONTENT_KEY = 'content';\n\nexport type MetaTag =\n | (CharsetMetaTag & ExcludeRestMetaTagKeys<typeof CHARSET_KEY>)\n | (HttpEquivMetaTag & ExcludeRestMetaTagKeys<typeof HTTP_EQUIV_KEY>)\n | (NameMetaTag & ExcludeRestMetaTagKeys<typeof NAME_KEY>)\n | (PropertyMetaTag & ExcludeRestMetaTagKeys<typeof PROPERTY_KEY>);\n\ntype CharsetMetaTag = { [CHARSET_KEY]: string };\ntype HttpEquivMetaTag = { [HTTP_EQUIV_KEY]: string; [CONTENT_KEY]: string };\ntype NameMetaTag = { [NAME_KEY]: string; [CONTENT_KEY]: string };\ntype PropertyMetaTag = { [PROPERTY_KEY]: string; [CONTENT_KEY]: string };\n\ntype MetaTagKey =\n | typeof CHARSET_KEY\n | typeof HTTP_EQUIV_KEY\n | typeof NAME_KEY\n | typeof PROPERTY_KEY;\ntype ExcludeRestMetaTagKeys<Key extends MetaTagKey> = {\n [K in Exclude<MetaTagKey, Key>]?: never;\n};\n\ntype MetaTagSelector =\n | typeof CHARSET_KEY\n | `${\n | typeof HTTP_EQUIV_SELECTOR_KEY\n | typeof NAME_KEY\n | typeof PROPERTY_KEY}=\"${string}\"`;\ntype MetaTagMap = Record<MetaTagSelector, MetaTag>;\n\nexport function updateMetaTagsOnRouteChange(): void {\n const router = inject(Router);\n const metaService = inject(Meta);\n\n router.events\n .pipe(filter((event) => event instanceof NavigationEnd))\n .subscribe(() => {\n const metaTagMap = getMetaTagMap(router.routerState.snapshot.root);\n\n for (const metaTagSelector in metaTagMap) {\n const metaTag = metaTagMap[\n metaTagSelector as MetaTagSelector\n ] as NgMetaTag;\n metaService.updateTag(metaTag, metaTagSelector);\n }\n });\n}\n\nfunction getMetaTagMap(route: ActivatedRouteSnapshot): MetaTagMap {\n const metaTagMap = {} as MetaTagMap;\n let currentRoute: ActivatedRouteSnapshot | null = route;\n\n while (currentRoute) {\n const metaTags: MetaTag[] = currentRoute.data[ROUTE_META_TAGS_KEY] ?? [];\n for (const metaTag of metaTags) {\n metaTagMap[getMetaTagSelector(metaTag)] = metaTag;\n }\n\n currentRoute = currentRoute.firstChild;\n }\n\n return metaTagMap;\n}\n\nfunction getMetaTagSelector(metaTag: MetaTag): MetaTagSelector {\n if (metaTag.name) {\n return `${NAME_KEY}=\"${metaTag.name}\"`;\n }\n\n if (metaTag.property) {\n return `${PROPERTY_KEY}=\"${metaTag.property}\"`;\n }\n\n if (metaTag.httpEquiv) {\n return `${HTTP_EQUIV_SELECTOR_KEY}=\"${metaTag.httpEquiv}\"`;\n }\n\n return CHARSET_KEY;\n}\n","import { RedirectRouteMeta, RouteConfig, RouteMeta } from './models';\nimport { ROUTE_META_TAGS_KEY } from './meta-tags';\n\nexport function toRouteConfig(routeMeta: RouteMeta | undefined): RouteConfig {\n if (!routeMeta) {\n return {};\n }\n\n if (isRedirectRouteMeta(routeMeta)) {\n return routeMeta;\n }\n\n const { meta, ...routeConfig } = routeMeta;\n\n if (Array.isArray(meta)) {\n routeConfig.data = { ...routeConfig.data, [ROUTE_META_TAGS_KEY]: meta };\n } else if (typeof meta === 'function') {\n routeConfig.resolve = {\n ...routeConfig.resolve,\n [ROUTE_META_TAGS_KEY]: meta,\n };\n }\n\n return routeConfig;\n}\n\nfunction isRedirectRouteMeta(\n routeMeta: RouteMeta\n): routeMeta is RedirectRouteMeta {\n return !!routeMeta.redirectTo;\n}\n","import { RouteExport } from './models';\n\nexport function toMarkdownModule(\n markdownFileFactory: () => Promise<string>\n): () => Promise<RouteExport> {\n return () =>\n Promise.all([import('@analogjs/content'), markdownFileFactory()]).then(\n ([{ parseRawContentFile, MarkdownComponent }, markdownFile]) => {\n const { content, attributes } = parseRawContentFile(markdownFile);\n const { title, meta } = attributes;\n\n return {\n default: MarkdownComponent,\n routeMeta: { data: { _analogContent: content }, title, meta },\n };\n }\n );\n}\n","/// <reference types=\"vite/client\" />\n\nimport type { Route } from '@angular/router';\n\nimport { RouteExport, RouteMeta } from './models';\nimport { toRouteConfig } from './route-config';\nimport { toMarkdownModule } from './markdown-helpers';\n\nconst FILES = import.meta.glob<RouteExport>([\n '/app/routes/**/*.ts',\n '/src/app/routes/**/*.ts',\n '/src/app/pages/**/*.page.ts',\n]);\n\nconst CONTENT_FILES = import.meta.glob<string>(\n ['/src/app/routes/**/*.md', '/src/app/pages/**/*.md'],\n {\n as: 'raw',\n }\n);\n\n/**\n * Function used to parse list of files and return\n * configuration of routes.\n *\n * @param files\n * @returns Array of routes\n */\nexport function getRoutes(\n files: Record<string, () => Promise<RouteExport | string>>\n) {\n const ROUTES = Object.keys(files).sort((a, b) => a.length - b.length);\n\n const routeConfigs = ROUTES.reduce<Route[]>(\n (routes: Route[], key: string) => {\n const module: () => Promise<RouteExport> = key.endsWith('.md')\n ? toMarkdownModule(files[key] as () => Promise<string>)\n : (files[key] as () => Promise<RouteExport>);\n\n const segments = key\n .replace(\n /^\\/(.*?)\\/routes|^\\/(.*?)\\/pages|\\/app\\/routes|\\.page|\\.(js|ts|md)$/g,\n ''\n )\n .replace(/\\[\\.{3}.+\\]/, '**')\n .replace(/\\[([^\\]]+)\\]/g, ':$1')\n .split('/')\n .filter(Boolean);\n\n segments.reduce((parent, segment, index) => {\n const path = segment\n .replace(/index|^\\(.*?\\)$/g, '')\n .replace(/\\./g, '/');\n const isIndex = !path;\n const isCatchall = path === '**';\n const pathMatch = isIndex ? 'full' : 'prefix';\n const root = index === 0;\n const leaf = index === segments.length - 1 && segments.length > 1;\n const node = !root && !leaf;\n const insert = /^\\w|\\//.test(path) && !isCatchall ? 'unshift' : 'push';\n\n if (root) {\n const dynamic = path.startsWith(':');\n if (dynamic) return parent;\n\n const last = segments.length === 1;\n if (last) {\n const newRoute = {\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ]),\n };\n\n routes?.[insert](newRoute as Route);\n return parent;\n }\n }\n\n if (root || node) {\n const current = root ? routes : parent._children;\n const found = current?.find((route: any) => route.path === path);\n\n if (found) {\n if (!found._children) {\n found._children = [];\n }\n\n found.pathMatch = pathMatch;\n } else {\n current?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ]),\n });\n }\n\n return (\n found ||\n (current?.[insert === 'unshift' ? 0 : current.length - 1] as Route)\n );\n }\n\n if (leaf) {\n parent?._children?.[insert]({\n path,\n pathMatch,\n _module: () => module(),\n loadChildren: () =>\n module().then((m) => [\n {\n path: '',\n component: m.default,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ]),\n });\n }\n\n if (parent._children) {\n parent.loadComponent = () =>\n parent._module().then((m: RouteExport) => m.default);\n parent.loadChildren = () =>\n parent._module().then((m: RouteExport) => {\n return [\n {\n path: '',\n children: parent._children,\n ...toRouteConfig(m.routeMeta as RouteMeta | undefined),\n },\n ];\n });\n }\n\n return parent;\n }, {} as Route & { _module: () => Promise<RouteExport>; _children: any[] });\n\n return routes;\n },\n []\n );\n\n return routeConfigs;\n}\n\nexport const routes: Route[] = [...getRoutes({ ...FILES, ...CONTENT_FILES })];\n","import { inject } from '@angular/core';\nimport { Route as NgRoute, Router } from '@angular/router';\nimport { ActivatedRoute } from '@angular/router';\n\ntype RouteOmitted =\n | 'component'\n | 'loadComponent'\n | 'loadChildren'\n | 'path'\n | 'pathMatch';\n\ntype RestrictedRoute = Omit<NgRoute, RouteOmitted>;\n\n/**\n * @deprecated Use `RouteMeta` type instead.\n * For more info see: https://github.com/analogjs/analog/issues/223\n *\n * Defines additional route config metadata. This\n * object is merged into the route config with\n * the predefined file-based route.\n *\n * @usageNotes\n *\n * ```\n * import { Component } from '@angular/core';\n * import { defineRouteMeta } from '@analogjs/router';\n *\n * export const routeMeta = defineRouteMeta({\n * title: 'Welcome'\n * });\n *\n * @Component({\n * template: `Home`,\n * standalone: true,\n * })\n * export default class HomeComponent {}\n * ```\n *\n * @param route\n * @returns\n */\nexport const defineRouteMeta = (route: RestrictedRoute) => {\n return route;\n};\n\n/**\n * Returns the instance of Angular Router\n *\n * @returns The router\n */\nexport const injectRouter = () => {\n return inject(Router);\n};\n\n/**\n * Returns the instance of the Activate Route for the component\n *\n * @returns The activated route\n */\nexport const injectActivatedRoute = () => {\n return inject(ActivatedRoute);\n};\n","import {\n ENVIRONMENT_INITIALIZER,\n EnvironmentProviders,\n makeEnvironmentProviders,\n Provider,\n} from '@angular/core';\nimport { provideRouter, RouterFeatures } from '@angular/router';\n\nimport { routes } from './routes';\nimport { updateMetaTagsOnRouteChange } from './meta-tags';\n\n/**\n * Sets up providers for the Angular router, and registers\n * file-based routes. Additional features can be provided\n * to further configure the behavior of the router.\n *\n * @param features\n * @returns Providers and features to configure the router with routes\n */\nexport function provideFileRouter(\n ...features: RouterFeatures[]\n): EnvironmentProviders {\n return makeEnvironmentProviders([\n // TODO: remove type casting after Angular >=15.1.1 upgrade\n // https://github.com/angular/angular/pull/48720\n (\n provideRouter(routes, ...features) as unknown as {\n ɵproviders: Provider[];\n }\n ).ɵproviders,\n {\n provide: ENVIRONMENT_INITIALIZER,\n multi: true,\n useValue: () => updateMetaTagsOnRouteChange(),\n },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { routes } from './lib/routes';
2
2
  export { defineRouteMeta, injectActivatedRoute, injectRouter, } from './lib/define-route';
3
- export { provideFileRouter } from './lib/provide-file-routes';
3
+ export { RouteMeta } from './lib/models';
4
+ export { provideFileRouter } from './lib/provide-file-router';
5
+ export { MetaTag } from './lib/meta-tags';
@@ -1,8 +1,11 @@
1
1
  import { Route as NgRoute, Router } from '@angular/router';
2
2
  import { ActivatedRoute } from '@angular/router';
3
- declare type RouteOmitted = 'component' | 'loadComponent' | 'loadChildren' | 'path' | 'pathMatch';
4
- declare type RestrictedRoute = Omit<NgRoute, RouteOmitted>;
3
+ type RouteOmitted = 'component' | 'loadComponent' | 'loadChildren' | 'path' | 'pathMatch';
4
+ type RestrictedRoute = Omit<NgRoute, RouteOmitted>;
5
5
  /**
6
+ * @deprecated Use `RouteMeta` type instead.
7
+ * For more info see: https://github.com/analogjs/analog/issues/223
8
+ *
6
9
  * Defines additional route config metadata. This
7
10
  * object is merged into the route config with
8
11
  * the predefined file-based route.
@@ -0,0 +1,2 @@
1
+ import { RouteExport } from './models';
2
+ export declare function toMarkdownModule(markdownFileFactory: () => Promise<string>): () => Promise<RouteExport>;
@@ -0,0 +1,28 @@
1
+ export declare const ROUTE_META_TAGS_KEY: unique symbol;
2
+ declare const CHARSET_KEY = "charset";
3
+ declare const HTTP_EQUIV_KEY = "httpEquiv";
4
+ declare const NAME_KEY = "name";
5
+ declare const PROPERTY_KEY = "property";
6
+ declare const CONTENT_KEY = "content";
7
+ export type MetaTag = (CharsetMetaTag & ExcludeRestMetaTagKeys<typeof CHARSET_KEY>) | (HttpEquivMetaTag & ExcludeRestMetaTagKeys<typeof HTTP_EQUIV_KEY>) | (NameMetaTag & ExcludeRestMetaTagKeys<typeof NAME_KEY>) | (PropertyMetaTag & ExcludeRestMetaTagKeys<typeof PROPERTY_KEY>);
8
+ type CharsetMetaTag = {
9
+ [CHARSET_KEY]: string;
10
+ };
11
+ type HttpEquivMetaTag = {
12
+ [HTTP_EQUIV_KEY]: string;
13
+ [CONTENT_KEY]: string;
14
+ };
15
+ type NameMetaTag = {
16
+ [NAME_KEY]: string;
17
+ [CONTENT_KEY]: string;
18
+ };
19
+ type PropertyMetaTag = {
20
+ [PROPERTY_KEY]: string;
21
+ [CONTENT_KEY]: string;
22
+ };
23
+ type MetaTagKey = typeof CHARSET_KEY | typeof HTTP_EQUIV_KEY | typeof NAME_KEY | typeof PROPERTY_KEY;
24
+ type ExcludeRestMetaTagKeys<Key extends MetaTagKey> = {
25
+ [K in Exclude<MetaTagKey, Key>]?: never;
26
+ };
27
+ export declare function updateMetaTagsOnRouteChange(): void;
28
+ export {};
@@ -0,0 +1,29 @@
1
+ import { Type } from '@angular/core';
2
+ import { CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanMatchFn, ResolveFn, Route } from '@angular/router';
3
+ import { defineRouteMeta } from './define-route';
4
+ import { MetaTag } from './meta-tags';
5
+ type OmittedRouteProps = 'path' | 'matcher' | 'component' | 'loadComponent' | 'children' | 'loadChildren' | 'canLoad' | 'outlet';
6
+ export type RouteConfig = Omit<Route, OmittedRouteProps>;
7
+ export interface DefaultRouteMeta extends Omit<Route, OmittedRouteProps | keyof RedirectRouteMeta> {
8
+ canActivate?: CanActivateFn[];
9
+ canActivateChild?: CanActivateChildFn[];
10
+ canDeactivate?: CanDeactivateFn<unknown>[];
11
+ canMatch?: CanMatchFn[];
12
+ resolve?: {
13
+ [key: string | symbol]: ResolveFn<unknown>;
14
+ };
15
+ title?: string | ResolveFn<string>;
16
+ meta?: MetaTag[] | ResolveFn<MetaTag[]>;
17
+ }
18
+ export interface RedirectRouteMeta {
19
+ redirectTo: string;
20
+ pathMatch?: Route['pathMatch'];
21
+ }
22
+ export type RouteMeta = (DefaultRouteMeta & {
23
+ redirectTo?: never;
24
+ }) | RedirectRouteMeta;
25
+ export type RouteExport = {
26
+ default: Type<unknown>;
27
+ routeMeta?: RouteMeta | ReturnType<typeof defineRouteMeta>;
28
+ };
29
+ export {};
@@ -1,3 +1,4 @@
1
+ import { EnvironmentProviders } from '@angular/core';
1
2
  import { RouterFeatures } from '@angular/router';
2
3
  /**
3
4
  * Sets up providers for the Angular router, and registers
@@ -7,4 +8,4 @@ import { RouterFeatures } from '@angular/router';
7
8
  * @param features
8
9
  * @returns Providers and features to configure the router with routes
9
10
  */
10
- export declare const provideFileRouter: (...features: RouterFeatures[]) => import("@angular/core").Provider[];
11
+ export declare function provideFileRouter(...features: RouterFeatures[]): EnvironmentProviders;
@@ -0,0 +1,2 @@
1
+ import { RouteConfig, RouteMeta } from './models';
2
+ export declare function toRouteConfig(routeMeta: RouteMeta | undefined): RouteConfig;
package/lib/routes.d.ts CHANGED
@@ -1,10 +1,5 @@
1
- import type { Type } from '@angular/core';
2
1
  import type { Route } from '@angular/router';
3
- import { defineRouteMeta } from './define-route';
4
- export declare type RouteExport = {
5
- default: Type<unknown>;
6
- routeMeta?: ReturnType<typeof defineRouteMeta>;
7
- };
2
+ import { RouteExport } from './models';
8
3
  /**
9
4
  * Function used to parse list of files and return
10
5
  * configuration of routes.
@@ -12,5 +7,5 @@ export declare type RouteExport = {
12
7
  * @param files
13
8
  * @returns Array of routes
14
9
  */
15
- export declare function getRoutes(files: Record<string, () => Promise<RouteExport>>): Route[];
10
+ export declare function getRoutes(files: Record<string, () => Promise<RouteExport | string>>): Route[];
16
11
  export declare const routes: Route[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/router",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-alpha.10",
4
4
  "description": "Filesystem-based routing for Angular",
5
5
  "author": "Brandon Roberts <robertsbt@gmail.com>",
6
6
  "keywords": [
@@ -19,8 +19,11 @@
19
19
  "url": "https://github.com/analogjs/analog.git"
20
20
  },
21
21
  "peerDependencies": {
22
- "@angular/core": "^14.0.0",
23
- "@angular/router": "^14.0.0"
22
+ "@angular/core": "^15.0.0 || ^16.0.0-next.0",
23
+ "@angular/router": "^15.0.0 || ^16.0.0-next.0"
24
+ },
25
+ "optionalDependencies": {
26
+ "@analogjs/content": "latest"
24
27
  },
25
28
  "dependencies": {
26
29
  "tslib": "^2.0.0"
@@ -1,14 +0,0 @@
1
- import { provideRouter } from '@angular/router';
2
- import { routes } from './routes';
3
- /**
4
- * Sets up providers for the Angular router, and registers
5
- * file-based routes. Additional features can be provided
6
- * to further configure the behavior of the router.
7
- *
8
- * @param features
9
- * @returns Providers and features to configure the router with routes
10
- */
11
- export const provideFileRouter = (...features) => {
12
- return provideRouter(routes, ...features);
13
- };
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZS1maWxlLXJvdXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3JvdXRlci9zcmMvbGliL3Byb3ZpZGUtZmlsZS1yb3V0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBa0IsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRWxDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEdBQUcsUUFBMEIsRUFBRSxFQUFFO0lBQ2pFLE9BQU8sYUFBYSxDQUFDLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDO0FBQzVDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHByb3ZpZGVSb3V0ZXIsIFJvdXRlckZlYXR1cmVzIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IHJvdXRlcyB9IGZyb20gJy4vcm91dGVzJztcblxuLyoqXG4gKiBTZXRzIHVwIHByb3ZpZGVycyBmb3IgdGhlIEFuZ3VsYXIgcm91dGVyLCBhbmQgcmVnaXN0ZXJzXG4gKiBmaWxlLWJhc2VkIHJvdXRlcy4gQWRkaXRpb25hbCBmZWF0dXJlcyBjYW4gYmUgcHJvdmlkZWRcbiAqIHRvIGZ1cnRoZXIgY29uZmlndXJlIHRoZSBiZWhhdmlvciBvZiB0aGUgcm91dGVyLlxuICpcbiAqIEBwYXJhbSBmZWF0dXJlc1xuICogQHJldHVybnMgUHJvdmlkZXJzIGFuZCBmZWF0dXJlcyB0byBjb25maWd1cmUgdGhlIHJvdXRlciB3aXRoIHJvdXRlc1xuICovXG5leHBvcnQgY29uc3QgcHJvdmlkZUZpbGVSb3V0ZXIgPSAoLi4uZmVhdHVyZXM6IFJvdXRlckZlYXR1cmVzW10pID0+IHtcbiAgcmV0dXJuIHByb3ZpZGVSb3V0ZXIocm91dGVzLCAuLi5mZWF0dXJlcyk7XG59O1xuIl19