@analogjs/router 3.0.0-alpha.19 → 3.0.0-alpha.20
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/content/package.json +4 -0
- package/fesm2022/analogjs-router-content.mjs +63 -0
- package/fesm2022/analogjs-router-content.mjs.map +1 -0
- package/fesm2022/analogjs-router-tanstack-query-server.mjs +22 -0
- package/fesm2022/analogjs-router-tanstack-query-server.mjs.map +1 -0
- package/fesm2022/analogjs-router-tanstack-query.mjs +1 -20
- package/fesm2022/analogjs-router-tanstack-query.mjs.map +1 -1
- package/fesm2022/analogjs-router.mjs +36 -18
- package/fesm2022/analogjs-router.mjs.map +1 -1
- package/fesm2022/debug.page.mjs +42 -28
- package/fesm2022/debug.page.mjs.map +1 -1
- package/fesm2022/provide-analog-query.mjs +23 -0
- package/fesm2022/provide-analog-query.mjs.map +1 -0
- package/fesm2022/route-files.mjs +345 -0
- package/fesm2022/route-files.mjs.map +1 -0
- package/fesm2022/routes.mjs +5 -360
- package/fesm2022/routes.mjs.map +1 -1
- package/package.json +16 -3
- package/tanstack-query/server/package.json +4 -0
- package/types/content/src/index.d.ts +4 -0
- package/types/content/src/lib/debug/routes.d.ts +10 -0
- package/types/{src → content/src}/lib/markdown-helpers.d.ts +1 -1
- package/types/content/src/lib/routes.d.ts +8 -0
- package/types/content/src/lib/with-content-routes.d.ts +2 -0
- package/types/src/index.d.ts +1 -1
- package/types/src/lib/debug/debug.page.d.ts +4 -2
- package/types/src/lib/provide-file-router-base.d.ts +4 -0
- package/types/src/lib/provide-file-router.d.ts +2 -8
- package/types/src/lib/route-builder.d.ts +5 -0
- package/types/src/lib/route-files.d.ts +18 -0
- package/types/src/lib/routes.d.ts +2 -10
- package/types/tanstack-query/server/src/index.d.ts +1 -0
package/fesm2022/routes.mjs
CHANGED
|
@@ -1,383 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as ANALOG_ROUTE_FILES, r as createRoutes$1 } from "./route-files.mjs";
|
|
2
2
|
import { InjectionToken, inject } from "@angular/core";
|
|
3
|
-
import { HttpClient } from "@angular/common/http";
|
|
4
|
-
import { firstValueFrom } from "rxjs";
|
|
5
|
-
import { injectAPIPrefix, injectBaseURL, injectInternalServerFetch } from "@analogjs/router/tokens";
|
|
6
|
-
import { DOCUMENT } from "@angular/common";
|
|
7
|
-
import { filter } from "rxjs/operators";
|
|
8
|
-
import { Meta } from "@angular/platform-browser";
|
|
9
|
-
//#region packages/router/src/lib/json-ld.ts
|
|
10
|
-
function isJsonLdObject(value) {
|
|
11
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
-
}
|
|
13
|
-
function normalizeJsonLd(value) {
|
|
14
|
-
if (Array.isArray(value)) return value.filter(isJsonLdObject);
|
|
15
|
-
return isJsonLdObject(value) ? [value] : [];
|
|
16
|
-
}
|
|
17
|
-
var ROUTE_JSON_LD_KEY = Symbol("@analogjs/router Route JSON-LD Key");
|
|
18
|
-
var JSON_LD_SCRIPT_SELECTOR = "script[data-analog-json-ld]";
|
|
19
|
-
function updateJsonLdOnRouteChange() {
|
|
20
|
-
const router = inject(Router);
|
|
21
|
-
const document = inject(DOCUMENT);
|
|
22
|
-
router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
|
|
23
|
-
applyJsonLdToDocument(document, getJsonLdEntries(router.routerState.snapshot.root));
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
function serializeJsonLd(entry) {
|
|
27
|
-
try {
|
|
28
|
-
return JSON.stringify(entry).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
29
|
-
} catch {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function getJsonLdEntries(route) {
|
|
34
|
-
const entries = [];
|
|
35
|
-
let currentRoute = route;
|
|
36
|
-
while (currentRoute) {
|
|
37
|
-
entries.push(...normalizeJsonLd(currentRoute.data[ROUTE_JSON_LD_KEY]));
|
|
38
|
-
currentRoute = currentRoute.firstChild;
|
|
39
|
-
}
|
|
40
|
-
return entries;
|
|
41
|
-
}
|
|
42
|
-
function applyJsonLdToDocument(document, entries) {
|
|
43
|
-
document.querySelectorAll(JSON_LD_SCRIPT_SELECTOR).forEach((element) => {
|
|
44
|
-
element.remove();
|
|
45
|
-
});
|
|
46
|
-
if (entries.length === 0) return;
|
|
47
|
-
const head = document.head || document.getElementsByTagName("head")[0];
|
|
48
|
-
if (!head) return;
|
|
49
|
-
entries.forEach((entry, index) => {
|
|
50
|
-
const serialized = serializeJsonLd(entry);
|
|
51
|
-
if (!serialized) return;
|
|
52
|
-
const script = document.createElement("script");
|
|
53
|
-
script.type = "application/ld+json";
|
|
54
|
-
script.setAttribute("data-analog-json-ld", "true");
|
|
55
|
-
script.setAttribute("data-analog-json-ld-index", String(index));
|
|
56
|
-
script.textContent = serialized;
|
|
57
|
-
head.appendChild(script);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region packages/router/src/lib/meta-tags.ts
|
|
62
|
-
var ROUTE_META_TAGS_KEY = Symbol("@analogjs/router Route Meta Tags Key");
|
|
63
|
-
var CHARSET_KEY = "charset";
|
|
64
|
-
var HTTP_EQUIV_SELECTOR_KEY = "http-equiv";
|
|
65
|
-
var NAME_KEY = "name";
|
|
66
|
-
var PROPERTY_KEY = "property";
|
|
67
|
-
var ITEMPROP_KEY = "itemprop";
|
|
68
|
-
function updateMetaTagsOnRouteChange() {
|
|
69
|
-
const router = inject(Router);
|
|
70
|
-
const metaService = inject(Meta);
|
|
71
|
-
router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe(() => {
|
|
72
|
-
const metaTagMap = getMetaTagMap(router.routerState.snapshot.root);
|
|
73
|
-
for (const metaTagSelector in metaTagMap) {
|
|
74
|
-
const metaTag = metaTagMap[metaTagSelector];
|
|
75
|
-
metaService.updateTag(metaTag, metaTagSelector);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
function getMetaTagMap(route) {
|
|
80
|
-
const metaTagMap = {};
|
|
81
|
-
let currentRoute = route;
|
|
82
|
-
while (currentRoute) {
|
|
83
|
-
const metaTags = currentRoute.data[ROUTE_META_TAGS_KEY] ?? [];
|
|
84
|
-
for (const metaTag of metaTags) metaTagMap[getMetaTagSelector(metaTag)] = metaTag;
|
|
85
|
-
currentRoute = currentRoute.firstChild;
|
|
86
|
-
}
|
|
87
|
-
return metaTagMap;
|
|
88
|
-
}
|
|
89
|
-
function getMetaTagSelector(metaTag) {
|
|
90
|
-
if (metaTag.name) return `${NAME_KEY}="${metaTag.name}"`;
|
|
91
|
-
if (metaTag.property) return `${PROPERTY_KEY}="${metaTag.property}"`;
|
|
92
|
-
if (metaTag.httpEquiv) return `${HTTP_EQUIV_SELECTOR_KEY}="${metaTag.httpEquiv}"`;
|
|
93
|
-
if (metaTag.itemprop) return `${ITEMPROP_KEY}="${metaTag.itemprop}"`;
|
|
94
|
-
return CHARSET_KEY;
|
|
95
|
-
}
|
|
96
|
-
//#endregion
|
|
97
|
-
//#region packages/router/src/lib/endpoints.ts
|
|
98
|
-
var ANALOG_META_KEY = Symbol("@analogjs/router Analog Route Metadata Key");
|
|
99
|
-
/**
|
|
100
|
-
* This variable reference is replaced with a glob of all route endpoints.
|
|
101
|
-
*/
|
|
102
|
-
var ANALOG_PAGE_ENDPOINTS = {};
|
|
103
|
-
//#endregion
|
|
104
|
-
//#region packages/router/src/lib/inject-route-endpoint-url.ts
|
|
105
|
-
function injectRouteEndpointURL(route) {
|
|
106
|
-
const routeConfig = route.routeConfig;
|
|
107
|
-
const apiPrefix = injectAPIPrefix();
|
|
108
|
-
const baseUrl = injectBaseURL();
|
|
109
|
-
const { queryParams, fragment: hash, params, parent } = route;
|
|
110
|
-
const segment = parent?.url.map((segment) => segment.path).join("/") || "";
|
|
111
|
-
const url = new URL("", {
|
|
112
|
-
"BASE_URL": "/",
|
|
113
|
-
"DEV": false,
|
|
114
|
-
"MODE": "production",
|
|
115
|
-
"PROD": true,
|
|
116
|
-
"SSR": false
|
|
117
|
-
}["VITE_ANALOG_PUBLIC_BASE_URL"] || baseUrl || (typeof window !== "undefined" && window.location.origin ? window.location.origin : ""));
|
|
118
|
-
url.pathname = `${url.pathname.endsWith("/") ? url.pathname : url.pathname + "/"}${apiPrefix}/_analog${routeConfig[ANALOG_META_KEY].endpoint}`;
|
|
119
|
-
url.search = `${new URLSearchParams(queryParams).toString()}`;
|
|
120
|
-
url.hash = hash ?? "";
|
|
121
|
-
Object.keys(params).forEach((param) => {
|
|
122
|
-
url.pathname = url.pathname.replace(`[${param}]`, params[param]);
|
|
123
|
-
});
|
|
124
|
-
url.pathname = url.pathname.replace("**", segment);
|
|
125
|
-
return url;
|
|
126
|
-
}
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region packages/router/src/lib/route-config.ts
|
|
129
|
-
function toRouteConfig(routeMeta) {
|
|
130
|
-
if (routeMeta && isRedirectRouteMeta$1(routeMeta)) return routeMeta;
|
|
131
|
-
const { meta, jsonLd, ...routeConfig } = routeMeta ?? {};
|
|
132
|
-
if (Array.isArray(meta)) routeConfig.data = {
|
|
133
|
-
...routeConfig.data,
|
|
134
|
-
[ROUTE_META_TAGS_KEY]: meta
|
|
135
|
-
};
|
|
136
|
-
else if (typeof meta === "function") routeConfig.resolve = {
|
|
137
|
-
...routeConfig.resolve,
|
|
138
|
-
[ROUTE_META_TAGS_KEY]: meta
|
|
139
|
-
};
|
|
140
|
-
if (Array.isArray(jsonLd) || isJsonLdObject(jsonLd)) routeConfig.data = {
|
|
141
|
-
...routeConfig.data,
|
|
142
|
-
[ROUTE_JSON_LD_KEY]: jsonLd
|
|
143
|
-
};
|
|
144
|
-
else if (typeof jsonLd === "function") routeConfig.resolve = {
|
|
145
|
-
...routeConfig.resolve,
|
|
146
|
-
[ROUTE_JSON_LD_KEY]: jsonLd
|
|
147
|
-
};
|
|
148
|
-
routeConfig.runGuardsAndResolvers = routeConfig.runGuardsAndResolvers ?? "paramsOrQueryParamsChange";
|
|
149
|
-
routeConfig.resolve = {
|
|
150
|
-
...routeConfig.resolve,
|
|
151
|
-
load: async (route) => {
|
|
152
|
-
if (ANALOG_PAGE_ENDPOINTS[route.routeConfig[ANALOG_META_KEY].endpointKey]) {
|
|
153
|
-
const http = inject(HttpClient);
|
|
154
|
-
const url = injectRouteEndpointURL(route);
|
|
155
|
-
const internalFetch = injectInternalServerFetch();
|
|
156
|
-
if (internalFetch) return internalFetch(url.pathname);
|
|
157
|
-
const globalFetch = globalThis.$fetch;
|
|
158
|
-
if (!!{
|
|
159
|
-
"BASE_URL": "/",
|
|
160
|
-
"DEV": false,
|
|
161
|
-
"MODE": "production",
|
|
162
|
-
"PROD": true,
|
|
163
|
-
"SSR": false
|
|
164
|
-
}["VITE_ANALOG_PUBLIC_BASE_URL"] && globalFetch) return globalFetch(url.pathname);
|
|
165
|
-
return firstValueFrom(http.get(`${url.href}`));
|
|
166
|
-
}
|
|
167
|
-
return {};
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
return routeConfig;
|
|
171
|
-
}
|
|
172
|
-
function isRedirectRouteMeta$1(routeMeta) {
|
|
173
|
-
return !!routeMeta.redirectTo;
|
|
174
|
-
}
|
|
175
|
-
//#endregion
|
|
176
|
-
//#region packages/router/src/lib/markdown-helpers.ts
|
|
177
|
-
var isNgZoneEnabled = typeof Zone !== "undefined" && !!Zone.root;
|
|
178
|
-
function toMarkdownModule(markdownFileFactory) {
|
|
179
|
-
return async () => {
|
|
180
|
-
const createLoader = () => Promise.all([import("@analogjs/content"), markdownFileFactory()]);
|
|
181
|
-
const [{ parseRawContentFile, MarkdownRouteComponent, ContentRenderer }, markdownFile] = await (isNgZoneEnabled ? Zone.root.run(createLoader) : createLoader());
|
|
182
|
-
const { content, attributes } = parseRawContentFile(markdownFile);
|
|
183
|
-
const { title, meta, jsonLd } = attributes;
|
|
184
|
-
return {
|
|
185
|
-
default: MarkdownRouteComponent,
|
|
186
|
-
routeMeta: {
|
|
187
|
-
data: { _analogContent: content },
|
|
188
|
-
title,
|
|
189
|
-
meta,
|
|
190
|
-
jsonLd,
|
|
191
|
-
resolve: { renderedAnalogContent: async () => {
|
|
192
|
-
const rendered = await inject(ContentRenderer).render(content);
|
|
193
|
-
return typeof rendered === "string" ? rendered : rendered.content;
|
|
194
|
-
} }
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
//#endregion
|
|
200
|
-
//#region packages/router/src/lib/constants.ts
|
|
201
|
-
var ENDPOINT_EXTENSION = ".server.ts";
|
|
202
|
-
//#endregion
|
|
203
3
|
//#region packages/router/src/lib/routes.ts
|
|
204
4
|
/**
|
|
205
|
-
* This variable reference is replaced with a glob of all page routes.
|
|
206
|
-
*/
|
|
207
|
-
var ANALOG_ROUTE_FILES = {};
|
|
208
|
-
/**
|
|
209
|
-
* This variable reference is replaced with a glob of all content routes.
|
|
210
|
-
*/
|
|
211
|
-
var ANALOG_CONTENT_ROUTE_FILES = {};
|
|
212
|
-
/**
|
|
213
5
|
* A function used to parse list of files and create configuration of routes.
|
|
214
6
|
*
|
|
215
7
|
* @param files
|
|
216
8
|
* @returns Array of routes
|
|
217
9
|
*/
|
|
218
10
|
function createRoutes(files, debug = false) {
|
|
219
|
-
|
|
220
|
-
if (filenames.length === 0) return [];
|
|
221
|
-
const rawRoutesByLevelMap = filenames.reduce((acc, filename) => {
|
|
222
|
-
const rawPath = toRawPath(filename);
|
|
223
|
-
const rawSegments = rawPath.split("/");
|
|
224
|
-
const level = rawSegments.length - 1;
|
|
225
|
-
const rawSegment = rawSegments[level];
|
|
226
|
-
const ancestorRawSegments = rawSegments.slice(0, level);
|
|
227
|
-
return {
|
|
228
|
-
...acc,
|
|
229
|
-
[level]: {
|
|
230
|
-
...acc[level],
|
|
231
|
-
[rawPath]: {
|
|
232
|
-
filename,
|
|
233
|
-
rawSegment,
|
|
234
|
-
ancestorRawSegments,
|
|
235
|
-
segment: toSegment(rawSegment),
|
|
236
|
-
level,
|
|
237
|
-
children: []
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
}, {});
|
|
242
|
-
const allLevels = Object.keys(rawRoutesByLevelMap).map(Number);
|
|
243
|
-
const maxLevel = Math.max(...allLevels);
|
|
244
|
-
for (let level = maxLevel; level > 0; level--) {
|
|
245
|
-
const rawRoutesMap = rawRoutesByLevelMap[level];
|
|
246
|
-
const rawPaths = Object.keys(rawRoutesMap);
|
|
247
|
-
for (const rawPath of rawPaths) {
|
|
248
|
-
const rawRoute = rawRoutesMap[rawPath];
|
|
249
|
-
const parentRawPath = rawRoute.ancestorRawSegments.join("/");
|
|
250
|
-
const parentRawSegmentIndex = rawRoute.ancestorRawSegments.length - 1;
|
|
251
|
-
const parentRawSegment = rawRoute.ancestorRawSegments[parentRawSegmentIndex];
|
|
252
|
-
rawRoutesByLevelMap[level - 1] ||= {};
|
|
253
|
-
rawRoutesByLevelMap[level - 1][parentRawPath] ||= {
|
|
254
|
-
filename: null,
|
|
255
|
-
rawSegment: parentRawSegment,
|
|
256
|
-
ancestorRawSegments: rawRoute.ancestorRawSegments.slice(0, parentRawSegmentIndex),
|
|
257
|
-
segment: toSegment(parentRawSegment),
|
|
258
|
-
level: level - 1,
|
|
259
|
-
children: []
|
|
260
|
-
};
|
|
261
|
-
rawRoutesByLevelMap[level - 1][parentRawPath].children.push(rawRoute);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
const rootRawRoutesMap = rawRoutesByLevelMap[0];
|
|
265
|
-
const rawRoutes = Object.keys(rootRawRoutesMap).map((segment) => rootRawRoutesMap[segment]);
|
|
266
|
-
sortRawRoutes(rawRoutes);
|
|
267
|
-
return toRoutes(rawRoutes, files, debug);
|
|
11
|
+
return createRoutes$1(files, (_filename, fileLoader) => fileLoader, debug);
|
|
268
12
|
}
|
|
269
|
-
|
|
270
|
-
return filename.replace(/^(?:[a-zA-Z]:[\\/])?(.*?)[\\/](?:routes|pages)[\\/]|(?:[\\/](?:app[\\/](?:routes|pages)|src[\\/]content)[\\/])|(\.page\.(js|ts|analog|ag)$)|(\.(ts|md|analog|ag)$)/g, "").replace(/\[\[\.\.\.([^\]]+)\]\]/g, "(opt-$1)").replace(/\[\.{3}.+\]/, "**").replace(/\[([^\]]+)\]/g, ":$1");
|
|
271
|
-
}
|
|
272
|
-
function toSegment(rawSegment) {
|
|
273
|
-
return rawSegment.replace(/index|\(.*?\)/g, "").replace(/\.|\/+/g, "/").replace(/^\/+|\/+$/g, "");
|
|
274
|
-
}
|
|
275
|
-
function createOptionalCatchAllMatcher(paramName) {
|
|
276
|
-
return (segments) => {
|
|
277
|
-
if (segments.length === 0) return null;
|
|
278
|
-
const joined = segments.map((s) => s.path).join("/");
|
|
279
|
-
return {
|
|
280
|
-
consumed: segments,
|
|
281
|
-
posParams: { [paramName]: new UrlSegment(joined, {}) }
|
|
282
|
-
};
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
function toRoutes(rawRoutes, files, debug = false) {
|
|
286
|
-
const routes = [];
|
|
287
|
-
for (const rawRoute of rawRoutes) {
|
|
288
|
-
const children = rawRoute.children.length > 0 ? toRoutes(rawRoute.children, files, debug) : void 0;
|
|
289
|
-
let module = void 0;
|
|
290
|
-
let analogMeta = void 0;
|
|
291
|
-
if (rawRoute.filename) {
|
|
292
|
-
const isMarkdownFile = rawRoute.filename.endsWith(".md");
|
|
293
|
-
if (!debug) module = isMarkdownFile ? toMarkdownModule(files[rawRoute.filename]) : files[rawRoute.filename];
|
|
294
|
-
const endpointKey = rawRoute.filename.replace(/\.page\.(ts|analog|ag)$/, ENDPOINT_EXTENSION);
|
|
295
|
-
analogMeta = {
|
|
296
|
-
endpoint: (rawRoute.filename.replace(/\.page\.(ts|analog|ag)$/, "").replace(/\[\[\.\.\..+\]\]/, "**").replace(/\[\.{3}.+\]/, "**").replace(/^(.*?)\/pages/, "/pages") || "").replace(/\./g, "/").replace(/\/\((.*?)\)$/, "/-$1-"),
|
|
297
|
-
endpointKey
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
const optCatchAllMatch = rawRoute.filename?.match(/\[\[\.\.\.([^\]]+)\]\]/);
|
|
301
|
-
const optCatchAllParam = optCatchAllMatch ? optCatchAllMatch[1] : null;
|
|
302
|
-
const route = module ? {
|
|
303
|
-
path: rawRoute.segment,
|
|
304
|
-
loadChildren: () => module().then((m) => {
|
|
305
|
-
const routeConfig = toRouteConfig(mergeRouteJsonLdIntoRouteMeta(m.routeMeta, m.routeJsonLd));
|
|
306
|
-
const hasRedirect = "redirectTo" in routeConfig;
|
|
307
|
-
return [{ ...hasRedirect ? {
|
|
308
|
-
path: "",
|
|
309
|
-
...routeConfig
|
|
310
|
-
} : {
|
|
311
|
-
path: "",
|
|
312
|
-
component: m.default,
|
|
313
|
-
...routeConfig,
|
|
314
|
-
children,
|
|
315
|
-
[ANALOG_META_KEY]: analogMeta
|
|
316
|
-
} }, ...optCatchAllParam ? [{
|
|
317
|
-
matcher: createOptionalCatchAllMatcher(optCatchAllParam),
|
|
318
|
-
...hasRedirect ? routeConfig : {
|
|
319
|
-
component: m.default,
|
|
320
|
-
...routeConfig,
|
|
321
|
-
[ANALOG_META_KEY]: analogMeta
|
|
322
|
-
}
|
|
323
|
-
}] : []];
|
|
324
|
-
})
|
|
325
|
-
} : {
|
|
326
|
-
path: rawRoute.segment,
|
|
327
|
-
...debug ? {
|
|
328
|
-
filename: rawRoute.filename ? rawRoute.filename : void 0,
|
|
329
|
-
isLayout: children && children.length > 0 ? true : false
|
|
330
|
-
} : {},
|
|
331
|
-
children
|
|
332
|
-
};
|
|
333
|
-
routes.push(route);
|
|
334
|
-
}
|
|
335
|
-
return routes;
|
|
336
|
-
}
|
|
337
|
-
function mergeRouteJsonLdIntoRouteMeta(routeMeta, routeJsonLd) {
|
|
338
|
-
if (!routeJsonLd) return routeMeta;
|
|
339
|
-
if (!routeMeta) return { jsonLd: routeJsonLd };
|
|
340
|
-
if (isRedirectRouteMeta(routeMeta) || routeMeta.jsonLd) return routeMeta;
|
|
341
|
-
return {
|
|
342
|
-
...routeMeta,
|
|
343
|
-
jsonLd: routeJsonLd
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
function isRedirectRouteMeta(routeMeta) {
|
|
347
|
-
return "redirectTo" in routeMeta && !!routeMeta.redirectTo;
|
|
348
|
-
}
|
|
349
|
-
function sortRawRoutes(rawRoutes) {
|
|
350
|
-
rawRoutes.sort((a, b) => {
|
|
351
|
-
let segmentA = deprioritizeSegment(a.segment);
|
|
352
|
-
let segmentB = deprioritizeSegment(b.segment);
|
|
353
|
-
if (a.children.length > b.children.length) segmentA = `~${segmentA}`;
|
|
354
|
-
else if (a.children.length < b.children.length) segmentB = `~${segmentB}`;
|
|
355
|
-
return segmentA > segmentB ? 1 : -1;
|
|
356
|
-
});
|
|
357
|
-
for (const rawRoute of rawRoutes) sortRawRoutes(rawRoute.children);
|
|
358
|
-
}
|
|
359
|
-
function deprioritizeSegment(segment) {
|
|
360
|
-
return segment.replace(":", "~~").replace("**", "~~~~");
|
|
361
|
-
}
|
|
362
|
-
var routes = createRoutes({
|
|
363
|
-
...ANALOG_ROUTE_FILES,
|
|
364
|
-
...ANALOG_CONTENT_ROUTE_FILES
|
|
365
|
-
});
|
|
13
|
+
var routes = createRoutes(ANALOG_ROUTE_FILES);
|
|
366
14
|
//#endregion
|
|
367
15
|
//#region packages/router/src/lib/debug/routes.ts
|
|
368
16
|
var DEBUG_ROUTES = new InjectionToken("@analogjs/router debug routes", {
|
|
369
17
|
providedIn: "root",
|
|
370
18
|
factory() {
|
|
371
|
-
return createRoutes(
|
|
372
|
-
...ANALOG_ROUTE_FILES,
|
|
373
|
-
...ANALOG_CONTENT_ROUTE_FILES
|
|
374
|
-
}, true);
|
|
19
|
+
return createRoutes(ANALOG_ROUTE_FILES, true);
|
|
375
20
|
}
|
|
376
21
|
});
|
|
377
22
|
function injectDebugRoutes() {
|
|
378
23
|
return inject(DEBUG_ROUTES);
|
|
379
24
|
}
|
|
380
25
|
//#endregion
|
|
381
|
-
export {
|
|
26
|
+
export { createRoutes as n, routes as r, injectDebugRoutes as t };
|
|
382
27
|
|
|
383
28
|
//# sourceMappingURL=routes.mjs.map
|
package/fesm2022/routes.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.mjs","names":[],"sources":["../../src/lib/json-ld.ts","../../src/lib/meta-tags.ts","../../src/lib/endpoints.ts","../../src/lib/inject-route-endpoint-url.ts","../../src/lib/route-config.ts","../../src/lib/markdown-helpers.ts","../../src/lib/constants.ts","../../src/lib/routes.ts","../../src/lib/debug/routes.ts"],"sourcesContent":["import { DOCUMENT } from '@angular/common';\nimport { inject } from '@angular/core';\nimport { ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs/operators';\n\nimport type { Graph, Thing, WithContext } from 'schema-dts';\n\nexport type JsonLdObject = Record<string, unknown>;\n\nexport function isJsonLdObject(value: unknown): value is JsonLdObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function normalizeJsonLd(value: unknown): JsonLdObject[] {\n if (Array.isArray(value)) {\n return value.filter(isJsonLdObject);\n }\n\n return isJsonLdObject(value) ? [value] : [];\n}\n\nexport type JsonLd = JsonLdObject | JsonLdObject[];\n\n/**\n * Typed JSON-LD document based on `schema-dts`.\n *\n * Accepts single Schema.org nodes (`WithContext<Thing>`),\n * `@graph`-based documents (`Graph`), or arrays of nodes.\n *\n * This is the canonical JSON-LD type for route authoring surfaces\n * (`routeMeta.jsonLd`, `routeJsonLd`, generated manifest).\n *\n * @example\n * ```ts\n * import type { WebPage, WithContext } from 'schema-dts';\n *\n * export const routeMeta = {\n * jsonLd: {\n * '@context': 'https://schema.org',\n * '@type': 'WebPage',\n * name: 'Products',\n * } satisfies WithContext<WebPage>,\n * };\n * ```\n */\nexport type AnalogJsonLdDocument =\n | WithContext<Thing>\n | Graph\n | Array<WithContext<Thing>>;\n\nexport const ROUTE_JSON_LD_KEY: unique symbol = Symbol(\n '@analogjs/router Route JSON-LD Key',\n);\nconst JSON_LD_SCRIPT_SELECTOR = 'script[data-analog-json-ld]';\n\nexport function updateJsonLdOnRouteChange(): void {\n const router = inject(Router);\n const document = inject(DOCUMENT);\n\n router.events\n .pipe(filter((event) => event instanceof NavigationEnd))\n .subscribe(() => {\n applyJsonLdToDocument(\n document,\n getJsonLdEntries(router.routerState.snapshot.root),\n );\n });\n}\n\nexport function serializeJsonLd(entry: JsonLdObject): string | null {\n try {\n return JSON.stringify(entry)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e')\n .replace(/&/g, '\\\\u0026')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n } catch {\n return null;\n }\n}\n\nfunction getJsonLdEntries(route: ActivatedRouteSnapshot): JsonLdObject[] {\n const entries: JsonLdObject[] = [];\n let currentRoute: ActivatedRouteSnapshot | null = route;\n\n while (currentRoute) {\n entries.push(...normalizeJsonLd(currentRoute.data[ROUTE_JSON_LD_KEY]));\n currentRoute = currentRoute.firstChild;\n }\n\n return entries;\n}\n\nfunction applyJsonLdToDocument(\n document: Document,\n entries: JsonLdObject[],\n): void {\n document.querySelectorAll(JSON_LD_SCRIPT_SELECTOR).forEach((element) => {\n element.remove();\n });\n\n if (entries.length === 0) {\n return;\n }\n\n const head = document.head || document.getElementsByTagName('head')[0];\n if (!head) {\n return;\n }\n\n entries.forEach((entry, index) => {\n const serialized = serializeJsonLd(entry);\n if (!serialized) {\n return;\n }\n\n const script = document.createElement('script');\n script.type = 'application/ld+json';\n script.setAttribute('data-analog-json-ld', 'true');\n script.setAttribute('data-analog-json-ld-index', String(index));\n script.textContent = serialized;\n head.appendChild(script);\n });\n}\n","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: unique symbol = 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';\nconst ITEMPROP_KEY = 'itemprop';\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 | (ItempropMetaTag & ExcludeRestMetaTagKeys<typeof ITEMPROP_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 };\ntype ItempropMetaTag = { [ITEMPROP_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\n | typeof ITEMPROP_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\n | typeof ITEMPROP_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 if (metaTag.itemprop) {\n return `${ITEMPROP_KEY}=\"${metaTag.itemprop}\"`;\n }\n\n return CHARSET_KEY;\n}\n","export const ANALOG_META_KEY: unique symbol = Symbol(\n '@analogjs/router Analog Route Metadata Key',\n);\n\n/**\n * This variable reference is replaced with a glob of all route endpoints.\n */\nexport const ANALOG_PAGE_ENDPOINTS: Record<string, () => Promise<unknown>> = {};\n","import type { ActivatedRouteSnapshot, Route } from '@angular/router';\nimport { injectBaseURL, injectAPIPrefix } from '@analogjs/router/tokens';\n\nimport { ANALOG_META_KEY } from './endpoints';\n\nexport function injectRouteEndpointURL(route: ActivatedRouteSnapshot): URL {\n const routeConfig = route.routeConfig as Route & {\n [ANALOG_META_KEY]: { endpoint: string; endpointKey: string };\n };\n\n const apiPrefix = injectAPIPrefix();\n const baseUrl = injectBaseURL();\n const { queryParams, fragment: hash, params, parent } = route;\n const segment = parent?.url.map((segment) => segment.path).join('/') || '';\n const url = new URL(\n '',\n import.meta.env['VITE_ANALOG_PUBLIC_BASE_URL'] ||\n baseUrl ||\n (typeof window !== 'undefined' && window.location.origin\n ? window.location.origin\n : ''),\n );\n url.pathname = `${\n url.pathname.endsWith('/') ? url.pathname : url.pathname + '/'\n }${apiPrefix}/_analog${routeConfig[ANALOG_META_KEY].endpoint}`;\n url.search = `${new URLSearchParams(queryParams).toString()}`;\n url.hash = hash ?? '';\n\n Object.keys(params).forEach((param) => {\n url.pathname = url.pathname.replace(`[${param}]`, params[param]);\n });\n url.pathname = url.pathname.replace('**', segment);\n\n return url;\n}\n","import { inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport type { Route } from '@angular/router';\nimport { firstValueFrom } from 'rxjs';\nimport {\n injectInternalServerFetch,\n type ServerInternalFetch,\n} from '@analogjs/router/tokens';\n\nimport {\n DefaultRouteMeta,\n RedirectRouteMeta,\n RouteConfig,\n RouteMeta,\n} from './models';\nimport { ROUTE_JSON_LD_KEY, isJsonLdObject } from './json-ld';\nimport { ROUTE_META_TAGS_KEY } from './meta-tags';\nimport { ANALOG_PAGE_ENDPOINTS, ANALOG_META_KEY } from './endpoints';\nimport { injectRouteEndpointURL } from './inject-route-endpoint-url';\n\nexport function toRouteConfig(routeMeta: RouteMeta | undefined): RouteConfig {\n if (routeMeta && isRedirectRouteMeta(routeMeta)) {\n return routeMeta;\n }\n\n const defaultMeta: DefaultRouteMeta = (routeMeta ?? {}) as DefaultRouteMeta;\n const { meta, jsonLd, ...routeConfig } = defaultMeta;\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 if (Array.isArray(jsonLd) || isJsonLdObject(jsonLd)) {\n routeConfig.data = { ...routeConfig.data, [ROUTE_JSON_LD_KEY]: jsonLd };\n } else if (typeof jsonLd === 'function') {\n routeConfig.resolve = {\n ...routeConfig.resolve,\n [ROUTE_JSON_LD_KEY]: jsonLd,\n };\n }\n\n routeConfig.runGuardsAndResolvers =\n routeConfig.runGuardsAndResolvers ?? 'paramsOrQueryParamsChange';\n routeConfig.resolve = {\n ...routeConfig.resolve,\n load: async (route) => {\n const routeConfig = route.routeConfig as Route & {\n [ANALOG_META_KEY]: { endpoint: string; endpointKey: string };\n };\n\n if (ANALOG_PAGE_ENDPOINTS[routeConfig[ANALOG_META_KEY].endpointKey]) {\n const http = inject(HttpClient);\n const url = injectRouteEndpointURL(route);\n const internalFetch = injectInternalServerFetch();\n\n if (internalFetch) {\n return internalFetch(url.pathname);\n }\n\n const globalFetch = (\n globalThis as unknown as { $fetch?: ServerInternalFetch }\n ).$fetch;\n if (!!import.meta.env['VITE_ANALOG_PUBLIC_BASE_URL'] && globalFetch) {\n return globalFetch(url.pathname);\n }\n\n return firstValueFrom(http.get(`${url.href}`));\n }\n\n return {};\n },\n };\n\n return routeConfig;\n}\n\nfunction isRedirectRouteMeta(\n routeMeta: RouteMeta,\n): routeMeta is RedirectRouteMeta {\n return !!routeMeta.redirectTo;\n}\n","import { inject } from '@angular/core';\nimport { RouteExport } from './models';\n\ndeclare const Zone: any;\ntype RenderResult = string | { content: string };\ntype ContentRendererLike = {\n render: (content: string) => Promise<RenderResult>;\n};\n\n// The Zone is currently enabled by default, so we wouldn't need this check.\n// However, leaving this open space will be useful if zone.js becomes optional\n// in the future. This means we won't have to modify the current code, and it will\n// continue to work seamlessly.\nconst isNgZoneEnabled = typeof Zone !== 'undefined' && !!Zone.root;\n\nexport function toMarkdownModule(\n markdownFileFactory: () => Promise<string>,\n): () => Promise<RouteExport> {\n return async () => {\n const createLoader = () =>\n Promise.all([import('@analogjs/content'), markdownFileFactory()]);\n\n const [\n { parseRawContentFile, MarkdownRouteComponent, ContentRenderer },\n markdownFile,\n ]: [typeof import('@analogjs/content'), string] = await (isNgZoneEnabled\n ? // We are not able to use `runOutsideAngular` because we are not inside\n // an injection context to retrieve the `NgZone` instance.\n // The `Zone.root.run` is required when the code is running in the\n // browser since asynchronous tasks being scheduled in the current context\n // are a reason for unnecessary change detection cycles.\n Zone.root.run(createLoader)\n : createLoader());\n\n const { content, attributes } = parseRawContentFile(markdownFile);\n const { title, meta, jsonLd } = attributes;\n\n return {\n default: MarkdownRouteComponent,\n routeMeta: {\n data: { _analogContent: content },\n title,\n meta,\n jsonLd,\n resolve: {\n renderedAnalogContent: async () => {\n const contentRenderer = inject<any>(\n ContentRenderer as any,\n ) as ContentRendererLike;\n const rendered = await contentRenderer.render(content);\n return typeof rendered === 'string' ? rendered : rendered.content;\n },\n },\n },\n };\n };\n}\n","export const ENDPOINT_EXTENSION = '.server.ts';\nexport const APP_DIR = 'src/app';\n","import { UrlSegment } from '@angular/router';\nimport type { Route } from '@angular/router';\nimport type { UrlMatcher } from '@angular/router';\n\nimport type { DefaultRouteMeta, RouteExport, RouteMeta } from './models';\nimport { toRouteConfig } from './route-config';\nimport { toMarkdownModule } from './markdown-helpers';\nimport { ENDPOINT_EXTENSION } from './constants';\nimport { ANALOG_META_KEY } from './endpoints';\n\n/**\n * This variable reference is replaced with a glob of all page routes.\n */\nexport const ANALOG_ROUTE_FILES = {};\n\n/**\n * This variable reference is replaced with a glob of all content routes.\n */\nexport const ANALOG_CONTENT_ROUTE_FILES = {};\n\nexport type Files = Record<string, () => Promise<RouteExport | string>>;\n\ntype RawRoute = {\n filename: string | null;\n rawSegment: string;\n ancestorRawSegments: string[];\n segment: string;\n level: number;\n children: RawRoute[];\n};\n\ntype RawRouteMap = Record<string, RawRoute>;\n\ntype RawRouteByLevelMap = Record<number, RawRouteMap>;\n\n/**\n * A function used to parse list of files and create configuration of routes.\n *\n * @param files\n * @returns Array of routes\n */\nexport function createRoutes(files: Files, debug = false): Route[] {\n const filenames = Object.keys(files);\n\n if (filenames.length === 0) {\n return [];\n }\n\n // map filenames to raw routes and group them by level\n const rawRoutesByLevelMap = filenames.reduce((acc, filename) => {\n const rawPath = toRawPath(filename);\n const rawSegments = rawPath.split('/');\n // nesting level starts at 0\n // rawPath: /products => level: 0\n // rawPath: /products/:id => level: 1\n const level = rawSegments.length - 1;\n const rawSegment = rawSegments[level];\n const ancestorRawSegments = rawSegments.slice(0, level);\n\n return {\n ...acc,\n [level]: {\n ...acc[level],\n [rawPath]: {\n filename,\n rawSegment,\n ancestorRawSegments,\n segment: toSegment(rawSegment),\n level,\n children: [],\n },\n },\n };\n }, {} as RawRouteByLevelMap);\n\n const allLevels = Object.keys(rawRoutesByLevelMap).map(Number);\n const maxLevel = Math.max(...allLevels);\n\n // add each raw route to its parent's children array\n for (let level = maxLevel; level > 0; level--) {\n const rawRoutesMap = rawRoutesByLevelMap[level];\n const rawPaths = Object.keys(rawRoutesMap);\n\n for (const rawPath of rawPaths) {\n const rawRoute = rawRoutesMap[rawPath];\n const parentRawPath = rawRoute.ancestorRawSegments.join('/');\n const parentRawSegmentIndex = rawRoute.ancestorRawSegments.length - 1;\n const parentRawSegment =\n rawRoute.ancestorRawSegments[parentRawSegmentIndex];\n\n // create the parent level and/or raw route if it does not exist\n // parent route won't exist for nested routes that don't have a layout route\n rawRoutesByLevelMap[level - 1] ||= {};\n rawRoutesByLevelMap[level - 1][parentRawPath] ||= {\n filename: null,\n rawSegment: parentRawSegment,\n ancestorRawSegments: rawRoute.ancestorRawSegments.slice(\n 0,\n parentRawSegmentIndex,\n ),\n segment: toSegment(parentRawSegment),\n level: level - 1,\n children: [],\n };\n\n rawRoutesByLevelMap[level - 1][parentRawPath].children.push(rawRoute);\n }\n }\n\n // only take raw routes from the root level\n // since they already contain nested routes as their children\n const rootRawRoutesMap = rawRoutesByLevelMap[0];\n const rawRoutes = Object.keys(rootRawRoutesMap).map(\n (segment) => rootRawRoutesMap[segment],\n );\n sortRawRoutes(rawRoutes);\n\n return toRoutes(rawRoutes, files, debug);\n}\n\nfunction toRawPath(filename: string): string {\n return (\n filename\n .replace(\n // convert to relative path and remove file extension\n /^(?:[a-zA-Z]:[\\\\/])?(.*?)[\\\\/](?:routes|pages)[\\\\/]|(?:[\\\\/](?:app[\\\\/](?:routes|pages)|src[\\\\/]content)[\\\\/])|(\\.page\\.(js|ts|analog|ag)$)|(\\.(ts|md|analog|ag)$)/g,\n '',\n )\n // [[...slug]] => placeholder (named empty) which is stripped by toSegment\n .replace(/\\[\\[\\.\\.\\.([^\\]]+)\\]\\]/g, '(opt-$1)')\n .replace(/\\[\\.{3}.+\\]/, '**') // [...not-found] => **\n .replace(/\\[([^\\]]+)\\]/g, ':$1')\n ); // [id] => :id\n}\n\nfunction toSegment(rawSegment: string): string {\n return rawSegment\n .replace(/index|\\(.*?\\)/g, '') // replace named empty segments\n .replace(/\\.|\\/+/g, '/') // replace dots with slashes and remove redundant slashes\n .replace(/^\\/+|\\/+$/g, ''); // remove trailing slashes\n}\n\nfunction createOptionalCatchAllMatcher(paramName: string): UrlMatcher {\n return (segments) => {\n if (segments.length === 0) {\n return null;\n }\n const joined = segments.map((s) => s.path).join('/');\n return {\n consumed: segments,\n posParams: { [paramName]: new UrlSegment(joined, {}) },\n };\n };\n}\n\nfunction toRoutes(rawRoutes: RawRoute[], files: Files, debug = false): Route[] {\n const routes: Route[] = [];\n\n for (const rawRoute of rawRoutes) {\n const children: Route[] | undefined =\n rawRoute.children.length > 0\n ? toRoutes(rawRoute.children, files, debug)\n : undefined;\n let module: (() => Promise<RouteExport>) | undefined = undefined;\n let analogMeta: { endpoint: string; endpointKey: string } | undefined =\n undefined;\n\n if (rawRoute.filename) {\n const isMarkdownFile = rawRoute.filename.endsWith('.md');\n\n if (!debug) {\n module = isMarkdownFile\n ? toMarkdownModule(files[rawRoute.filename] as () => Promise<string>)\n : (files[rawRoute.filename] as () => Promise<RouteExport>);\n }\n\n const endpointKey = rawRoute.filename.replace(\n /\\.page\\.(ts|analog|ag)$/,\n ENDPOINT_EXTENSION,\n );\n\n // get endpoint path\n const rawEndpoint = rawRoute.filename\n .replace(/\\.page\\.(ts|analog|ag)$/, '')\n .replace(/\\[\\[\\.\\.\\..+\\]\\]/, '**')\n .replace(/\\[\\.{3}.+\\]/, '**') // [...not-found] => **\n .replace(/^(.*?)\\/pages/, '/pages');\n\n // replace periods, remove (index) paths\n const endpoint = (rawEndpoint || '')\n .replace(/\\./g, '/')\n .replace(/\\/\\((.*?)\\)$/, '/-$1-');\n\n analogMeta = {\n endpoint,\n endpointKey,\n };\n }\n\n // Detect Next.js-style optional catch-all at this node: [[...param]]\n const optCatchAllMatch = rawRoute.filename?.match(/\\[\\[\\.\\.\\.([^\\]]+)\\]\\]/);\n const optCatchAllParam = optCatchAllMatch ? optCatchAllMatch[1] : null;\n\n type DebugRoute = Route & {\n filename?: string | null | undefined;\n isLayout?: boolean;\n };\n\n const route: Route & { meta?: typeof analogMeta } & DebugRoute = module\n ? {\n path: rawRoute.segment,\n loadChildren: () =>\n module!().then((m) => {\n if (import.meta.env.DEV) {\n const hasModuleDefault = !!m.default;\n const hasRedirect = !!m.routeMeta?.redirectTo;\n\n if (!hasModuleDefault && !hasRedirect) {\n console.warn(\n `[Analog] Missing default export at ${rawRoute.filename}`,\n );\n }\n }\n\n const routeMeta = mergeRouteJsonLdIntoRouteMeta(\n m.routeMeta as RouteMeta | undefined,\n m.routeJsonLd,\n );\n\n const routeConfig = toRouteConfig(routeMeta);\n const hasRedirect = 'redirectTo' in routeConfig;\n const baseChild = hasRedirect\n ? {\n path: '',\n ...routeConfig,\n }\n : {\n path: '',\n component: m.default,\n ...routeConfig,\n children,\n [ANALOG_META_KEY]: analogMeta,\n };\n\n // Base route first so static matches win, then optional catch-all matcher\n return [\n {\n ...baseChild,\n },\n ...(optCatchAllParam\n ? [\n {\n matcher:\n createOptionalCatchAllMatcher(optCatchAllParam),\n ...(hasRedirect\n ? routeConfig\n : {\n component: m.default,\n ...routeConfig,\n [ANALOG_META_KEY]: analogMeta,\n }),\n },\n ]\n : []),\n ];\n }),\n }\n : {\n path: rawRoute.segment,\n ...(debug\n ? {\n filename: rawRoute.filename ? rawRoute.filename : undefined,\n isLayout: children && children.length > 0 ? true : false,\n }\n : {}),\n children,\n };\n\n routes.push(route);\n }\n\n return routes;\n}\n\nfunction mergeRouteJsonLdIntoRouteMeta(\n routeMeta: RouteMeta | undefined,\n routeJsonLd: RouteExport['routeJsonLd'],\n): RouteMeta | undefined {\n if (!routeJsonLd) {\n return routeMeta;\n }\n\n if (!routeMeta) {\n return { jsonLd: routeJsonLd };\n }\n\n if (isRedirectRouteMeta(routeMeta) || routeMeta.jsonLd) {\n return routeMeta;\n }\n\n return {\n ...routeMeta,\n jsonLd: routeJsonLd,\n };\n}\n\nfunction isRedirectRouteMeta(\n routeMeta: RouteMeta,\n): routeMeta is Exclude<RouteMeta, DefaultRouteMeta> {\n return 'redirectTo' in routeMeta && !!routeMeta.redirectTo;\n}\n\nfunction sortRawRoutes(rawRoutes: RawRoute[]): void {\n rawRoutes.sort((a, b) => {\n let segmentA = deprioritizeSegment(a.segment);\n let segmentB = deprioritizeSegment(b.segment);\n\n // prioritize routes with fewer children\n if (a.children.length > b.children.length) {\n segmentA = `~${segmentA}`;\n } else if (a.children.length < b.children.length) {\n segmentB = `~${segmentB}`;\n }\n\n return segmentA > segmentB ? 1 : -1;\n });\n\n for (const rawRoute of rawRoutes) {\n sortRawRoutes(rawRoute.children);\n }\n}\n\nfunction deprioritizeSegment(segment: string): string {\n // deprioritize param and wildcard segments\n return segment.replace(':', '~~').replace('**', '~~~~');\n}\n\nexport const routes: Route[] = createRoutes({\n ...ANALOG_ROUTE_FILES,\n ...ANALOG_CONTENT_ROUTE_FILES,\n});\n","import { inject, InjectionToken } from '@angular/core';\nimport { Route } from '@angular/router';\n\nimport {\n ANALOG_CONTENT_ROUTE_FILES,\n ANALOG_ROUTE_FILES,\n createRoutes,\n} from '../routes';\n\nexport const DEBUG_ROUTES: InjectionToken<(Route & DebugRoute)[]> =\n new InjectionToken<(Route & DebugRoute)[]>('@analogjs/router debug routes', {\n providedIn: 'root',\n factory() {\n const debugRoutes = createRoutes(\n {\n ...ANALOG_ROUTE_FILES,\n ...ANALOG_CONTENT_ROUTE_FILES,\n },\n true,\n );\n\n return debugRoutes as (Route & DebugRoute)[];\n },\n });\n\nexport type DebugRoute = {\n path: string;\n filename: string;\n isLayout: boolean;\n children?: DebugRoute[];\n};\n\nexport function injectDebugRoutes(): (Route & DebugRoute)[] {\n return inject(DEBUG_ROUTES);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"routes.mjs","names":[],"sources":["../../src/lib/routes.ts","../../src/lib/debug/routes.ts"],"sourcesContent":["import type { Route } from '@angular/router';\n\nimport type { RouteExport } from './models';\nimport { createRoutes as createBaseRoutes } from './route-builder';\nimport { ANALOG_ROUTE_FILES, type Files } from './route-files';\n\n/**\n * A function used to parse list of files and create configuration of routes.\n *\n * @param files\n * @returns Array of routes\n */\nexport function createRoutes(files: Files, debug = false): Route[] {\n return createBaseRoutes(\n files,\n (_filename, fileLoader) => fileLoader as () => Promise<RouteExport>,\n debug,\n );\n}\n\nexport { ANALOG_ROUTE_FILES } from './route-files';\n\nexport const routes: Route[] = createRoutes(ANALOG_ROUTE_FILES);\n","import { inject, InjectionToken } from '@angular/core';\nimport { Route } from '@angular/router';\n\nimport { ANALOG_ROUTE_FILES, createRoutes } from '../routes';\n\nexport const DEBUG_ROUTES: InjectionToken<(Route & DebugRoute)[]> =\n new InjectionToken<(Route & DebugRoute)[]>('@analogjs/router debug routes', {\n providedIn: 'root',\n factory() {\n const debugRoutes = createRoutes(ANALOG_ROUTE_FILES, true);\n\n return debugRoutes as (Route & DebugRoute)[];\n },\n });\n\nexport type DebugRoute = {\n path: string;\n filename: string;\n isLayout: boolean;\n children?: DebugRoute[];\n};\n\nexport function injectDebugRoutes(): (Route & DebugRoute)[] {\n return inject(DEBUG_ROUTES);\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,aAAa,OAAc,QAAQ,OAAgB;AACjE,QAAO,eACL,QACC,WAAW,eAAe,YAC3B,MACD;;AAKH,IAAa,SAAkB,aAAa,mBAAmB;;;ACjB/D,IAAa,eACX,IAAI,eAAuC,iCAAiC;CAC1E,YAAY;CACZ,UAAU;AAGR,SAFoB,aAAa,oBAAyB,KAAA;;CAI7D,CAAC;AASJ,SAAgB,oBAA4C;AAC1D,QAAO,OAAO,aAAa"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@analogjs/router",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.20",
|
|
4
4
|
"description": "Filesystem-based routing for Angular",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Brandon Roberts <robertsbt@gmail.com>",
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
"import": "./fesm2022/analogjs-router.mjs",
|
|
14
14
|
"default": "./fesm2022/analogjs-router.mjs"
|
|
15
15
|
},
|
|
16
|
+
"./content": {
|
|
17
|
+
"types": "./types/content/src/index.d.ts",
|
|
18
|
+
"import": "./fesm2022/analogjs-router-content.mjs",
|
|
19
|
+
"default": "./fesm2022/analogjs-router-content.mjs"
|
|
20
|
+
},
|
|
16
21
|
"./server": {
|
|
17
22
|
"types": "./types/server/src/index.d.ts",
|
|
18
23
|
"import": "./fesm2022/analogjs-router-server.mjs",
|
|
@@ -28,6 +33,11 @@
|
|
|
28
33
|
"import": "./fesm2022/analogjs-router-tanstack-query.mjs",
|
|
29
34
|
"default": "./fesm2022/analogjs-router-tanstack-query.mjs"
|
|
30
35
|
},
|
|
36
|
+
"./tanstack-query/server": {
|
|
37
|
+
"types": "./types/tanstack-query/server/src/index.d.ts",
|
|
38
|
+
"import": "./fesm2022/analogjs-router-tanstack-query-server.mjs",
|
|
39
|
+
"default": "./fesm2022/analogjs-router-tanstack-query-server.mjs"
|
|
40
|
+
},
|
|
31
41
|
"./tokens": {
|
|
32
42
|
"types": "./types/tokens/src/index.d.ts",
|
|
33
43
|
"import": "./fesm2022/analogjs-router-tokens.mjs",
|
|
@@ -54,7 +64,7 @@
|
|
|
54
64
|
"url": "https://github.com/sponsors/brandonroberts"
|
|
55
65
|
},
|
|
56
66
|
"peerDependencies": {
|
|
57
|
-
"@analogjs/content": "^3.0.0-alpha.
|
|
67
|
+
"@analogjs/content": "^3.0.0-alpha.20",
|
|
58
68
|
"@angular/core": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
59
69
|
"@angular/platform-server": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
60
70
|
"@angular/router": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
|
|
@@ -62,6 +72,9 @@
|
|
|
62
72
|
"schema-dts": "^2.0.0"
|
|
63
73
|
},
|
|
64
74
|
"peerDependenciesMeta": {
|
|
75
|
+
"@analogjs/content": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
65
78
|
"@angular/platform-server": {
|
|
66
79
|
"optional": true
|
|
67
80
|
},
|
|
@@ -77,7 +90,7 @@
|
|
|
77
90
|
"tslib": "^2.0.0"
|
|
78
91
|
},
|
|
79
92
|
"devDependencies": {
|
|
80
|
-
"@analogjs/vite-plugin-angular": "^3.0.0-alpha.
|
|
93
|
+
"@analogjs/vite-plugin-angular": "^3.0.0-alpha.20"
|
|
81
94
|
},
|
|
82
95
|
"ng-update": {
|
|
83
96
|
"packageGroup": [
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import { Route } from '@angular/router';
|
|
3
|
+
export declare const DEBUG_CONTENT_ROUTES: InjectionToken<(Route & DebugRoute)[]>;
|
|
4
|
+
export type DebugRoute = {
|
|
5
|
+
path: string;
|
|
6
|
+
filename: string;
|
|
7
|
+
isLayout: boolean;
|
|
8
|
+
children?: DebugRoute[];
|
|
9
|
+
};
|
|
10
|
+
export declare function injectDebugContentRoutes(): (Route & DebugRoute)[];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RouteExport } from '
|
|
1
|
+
import type { RouteExport } from '../../../src/lib/models';
|
|
2
2
|
export declare function toMarkdownModule(markdownFileFactory: () => Promise<string>): () => Promise<RouteExport>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Route } from '@angular/router';
|
|
2
|
+
import type { RouteExport } from '../../../src/lib/models';
|
|
3
|
+
/**
|
|
4
|
+
* This variable reference is replaced with a glob of all content routes.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ANALOG_CONTENT_ROUTE_FILES: {};
|
|
7
|
+
export type Files = Record<string, () => Promise<RouteExport | string>>;
|
|
8
|
+
export declare function createContentRoutes(files: Files, debug?: boolean): Route[];
|
package/types/src/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { RouteExport } from './lib/models';
|
|
2
|
-
export type { Files } from './lib/
|
|
2
|
+
export type { Files } from './lib/route-files';
|
|
3
3
|
export { routes, createRoutes } from './lib/routes';
|
|
4
4
|
export { defineRouteMeta, injectActivatedRoute, injectRouter, } from './lib/define-route';
|
|
5
5
|
export type { RouteMeta } from './lib/models';
|
|
@@ -6,12 +6,14 @@ type CollectedRoute = {
|
|
|
6
6
|
filename: string;
|
|
7
7
|
file: string;
|
|
8
8
|
isLayout: boolean;
|
|
9
|
+
source: 'page' | 'content';
|
|
9
10
|
};
|
|
10
11
|
export default class DebugRoutesComponent implements OnInit {
|
|
11
12
|
collectedRoutes: CollectedRoute[];
|
|
12
|
-
debugRoutes
|
|
13
|
+
private debugRoutes;
|
|
14
|
+
private extraSources;
|
|
13
15
|
ngOnInit(): void;
|
|
14
|
-
traverseRoutes(routes: DebugRoute[], parent?: string): void;
|
|
16
|
+
traverseRoutes(routes: DebugRoute[], parent?: string, source?: 'page' | 'content'): void;
|
|
15
17
|
static ɵfac: i0.ɵɵFactoryDeclaration<DebugRoutesComponent, never>;
|
|
16
18
|
static ɵcmp: i0.ɵɵComponentDeclaration<DebugRoutesComponent, "analogjs-debug-routes-page", never, {}, {}, never, never, true, never>;
|
|
17
19
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { EnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { RouterFeatures, Routes } from '@angular/router';
|
|
3
|
+
export declare function provideFileRouterWithRoutes(...features: RouterFeatures[]): EnvironmentProviders;
|
|
4
|
+
export declare function withExtraRoutes(routes: Routes): RouterFeatures;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EnvironmentProviders } from '@angular/core';
|
|
2
|
-
import { RouterFeatures
|
|
2
|
+
import { RouterFeatures } from '@angular/router';
|
|
3
3
|
/**
|
|
4
4
|
* Sets up providers for the Angular router, and registers
|
|
5
5
|
* file-based routes. Additional features can be provided
|
|
@@ -9,10 +9,4 @@ import { RouterFeatures, Routes } from '@angular/router';
|
|
|
9
9
|
* @returns Providers and features to configure the router with routes
|
|
10
10
|
*/
|
|
11
11
|
export declare function provideFileRouter(...features: RouterFeatures[]): EnvironmentProviders;
|
|
12
|
-
|
|
13
|
-
* Provides extra custom routes in addition to the routes
|
|
14
|
-
* discovered from the filesystem-based routing. These routes are
|
|
15
|
-
* inserted before the filesystem-based routes, and take priority in
|
|
16
|
-
* route matching.
|
|
17
|
-
*/
|
|
18
|
-
export declare function withExtraRoutes(routes: Routes): RouterFeatures;
|
|
12
|
+
export { withExtraRoutes } from './provide-file-router-base';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Route } from '@angular/router';
|
|
2
|
+
import type { RouteExport } from './models';
|
|
3
|
+
export type RouteModuleFactory = () => Promise<RouteExport>;
|
|
4
|
+
export type RouteModuleResolver<TFile> = (filename: string, fileLoader: () => Promise<TFile>) => RouteModuleFactory;
|
|
5
|
+
export declare function createRoutes<TFile>(files: Record<string, () => Promise<TFile>>, resolveModule: RouteModuleResolver<TFile>, debug?: boolean): Route[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import type { RouteExport } from './models';
|
|
3
|
+
export type Files = Record<string, () => Promise<RouteExport>>;
|
|
4
|
+
/**
|
|
5
|
+
* This variable reference is replaced with a glob of all page routes.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ANALOG_ROUTE_FILES: {};
|
|
8
|
+
export interface ExtraRouteFileSource {
|
|
9
|
+
files: Record<string, () => Promise<unknown>>;
|
|
10
|
+
resolveModule: (filename: string, fileLoader: () => Promise<unknown>) => () => Promise<RouteExport>;
|
|
11
|
+
}
|
|
12
|
+
export declare const ANALOG_EXTRA_ROUTE_FILE_SOURCES: InjectionToken<ExtraRouteFileSource[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Replaced at build time by the Vite router plugin with the number of
|
|
15
|
+
* discovered content route files. Used in dev mode to warn when content
|
|
16
|
+
* files exist but `withContentRoutes()` is not configured.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ANALOG_CONTENT_FILE_COUNT = 0;
|