@qwik.dev/router 2.0.0-beta.10 → 2.0.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/adapters/azure-swa/vite/index.cjs +61 -5
- package/lib/adapters/azure-swa/vite/index.mjs +26 -201
- package/lib/adapters/bun-server/vite/index.cjs +27 -5
- package/lib/adapters/bun-server/vite/index.mjs +14 -196
- package/lib/adapters/cloud-run/vite/index.cjs +24 -5
- package/lib/adapters/cloud-run/vite/index.mjs +13 -195
- package/lib/adapters/cloudflare-pages/vite/index.cjs +65 -1
- package/lib/adapters/cloudflare-pages/vite/index.mjs +63 -4
- package/lib/adapters/deno-server/vite/index.cjs +39 -5
- package/lib/adapters/deno-server/vite/index.mjs +16 -198
- package/lib/adapters/netlify-edge/vite/index.cjs +88 -6
- package/lib/adapters/netlify-edge/vite/index.mjs +56 -240
- package/lib/adapters/node-server/vite/index.cjs +27 -5
- package/lib/adapters/node-server/vite/index.mjs +14 -196
- package/lib/adapters/shared/vite/index.cjs +303 -2
- package/lib/adapters/shared/vite/index.d.ts +4 -4
- package/lib/adapters/shared/vite/index.mjs +248 -143
- package/lib/adapters/ssg/vite/index.cjs +19 -5
- package/lib/adapters/ssg/vite/index.mjs +11 -193
- package/lib/adapters/vercel-edge/vite/index.cjs +81 -5
- package/lib/adapters/vercel-edge/vite/index.d.ts +1 -1
- package/lib/adapters/vercel-edge/vite/index.mjs +48 -229
- package/lib/chunks/error-handler.cjs +58 -0
- package/lib/chunks/error-handler.mjs +59 -0
- package/lib/chunks/format-error.cjs +136 -0
- package/lib/chunks/format-error.mjs +137 -0
- package/lib/chunks/fs.cjs +274 -0
- package/lib/chunks/fs.mjs +275 -0
- package/lib/chunks/index.cjs +877 -0
- package/lib/chunks/index.mjs +876 -0
- package/lib/chunks/mime-types.cjs +52 -0
- package/lib/chunks/mime-types.mjs +53 -0
- package/lib/chunks/routing.qwik.cjs +452 -0
- package/lib/chunks/routing.qwik.mjs +453 -0
- package/lib/chunks/types.qwik.cjs +24 -0
- package/lib/chunks/types.qwik.mjs +25 -0
- package/lib/index.d.ts +9 -3
- package/lib/index.qwik.cjs +543 -1001
- package/lib/index.qwik.mjs +512 -972
- package/lib/middleware/aws-lambda/index.cjs +52 -1
- package/lib/middleware/aws-lambda/index.mjs +37 -26
- package/lib/middleware/azure-swa/index.cjs +92 -1
- package/lib/middleware/azure-swa/index.mjs +64 -46
- package/lib/middleware/bun/index.cjs +143 -1
- package/lib/middleware/bun/index.mjs +103 -117
- package/lib/middleware/cloudflare-pages/index.cjs +96 -1
- package/lib/middleware/cloudflare-pages/index.mjs +68 -47
- package/lib/middleware/deno/index.cjs +130 -1
- package/lib/middleware/deno/index.mjs +93 -112
- package/lib/middleware/firebase/index.cjs +33 -1
- package/lib/middleware/firebase/index.mjs +25 -16
- package/lib/middleware/netlify-edge/index.cjs +71 -1
- package/lib/middleware/netlify-edge/index.mjs +52 -36
- package/lib/middleware/node/index.cjs +219 -1
- package/lib/middleware/node/index.mjs +178 -165
- package/lib/middleware/request-handler/index.cjs +1488 -18
- package/lib/middleware/request-handler/index.d.ts +20 -2
- package/lib/middleware/request-handler/index.mjs +1225 -873
- package/lib/middleware/vercel-edge/index.cjs +98 -1
- package/lib/middleware/vercel-edge/index.mjs +71 -47
- package/lib/service-worker/index.cjs +5 -0
- package/lib/service-worker/index.mjs +5 -0
- package/lib/ssg/index.cjs +15 -1
- package/lib/ssg/index.mjs +12 -19
- package/lib/vite/index.cjs +2006 -27
- package/lib/vite/index.d.ts +9 -9
- package/lib/vite/index.mjs +1597 -1216
- package/package.json +9 -8
- package/lib/adapters/azure-swa/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/azure-swa/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/azure-swa/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/azure-swa/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/azure-swa/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/azure-swa/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/bun-server/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/bun-server/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/bun-server/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/bun-server/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/bun-server/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/bun-server/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/cloud-run/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/cloud-run/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/cloud-run/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/cloud-run/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/cloud-run/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/cloud-run/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/cloudflare-pages/vite/index-BIeHg2Cj.cjs +0 -5
- package/lib/adapters/cloudflare-pages/vite/index-C455V8_A.cjs +0 -1
- package/lib/adapters/cloudflare-pages/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/cloudflare-pages/vite/index-D3HITboM.js +0 -645
- package/lib/adapters/cloudflare-pages/vite/index-DKcVHRBy.cjs +0 -11
- package/lib/adapters/cloudflare-pages/vite/index-DwovcBp3.js +0 -22
- package/lib/adapters/cloudflare-pages/vite/index-bogwy7wh.js +0 -250
- package/lib/adapters/cloudflare-pages/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/deno-server/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/deno-server/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/deno-server/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/deno-server/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/deno-server/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/deno-server/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/netlify-edge/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/netlify-edge/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/netlify-edge/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/netlify-edge/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/netlify-edge/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/netlify-edge/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/node-server/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/node-server/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/node-server/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/node-server/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/node-server/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/node-server/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/shared/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/shared/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/shared/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/shared/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/shared/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/shared/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/ssg/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/ssg/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/ssg/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/ssg/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/ssg/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/ssg/vite/index-vQuPcef3.cjs +0 -1
- package/lib/adapters/vercel-edge/vite/index-BqUeglYs.cjs +0 -1
- package/lib/adapters/vercel-edge/vite/index-CBIchDYq.js +0 -651
- package/lib/adapters/vercel-edge/vite/index-ClHGw5z1.js +0 -6
- package/lib/adapters/vercel-edge/vite/index-CrwlB95_.js +0 -22
- package/lib/adapters/vercel-edge/vite/index-DTIOTwZo.cjs +0 -11
- package/lib/adapters/vercel-edge/vite/index-vQuPcef3.cjs +0 -1
- package/lib/service-worker.cjs +0 -1
- package/lib/service-worker.mjs +0 -5
- package/lib/ssg/deno.cjs +0 -1
- package/lib/ssg/deno.mjs +0 -6
- package/lib/ssg/index-CBIchDYq.js +0 -651
- package/lib/ssg/index-ClHGw5z1.js +0 -6
- package/lib/ssg/index-DTIOTwZo.cjs +0 -11
- package/lib/ssg/index-vQuPcef3.cjs +0 -1
- package/lib/ssg/node.cjs +0 -11
- package/lib/ssg/node.mjs +0 -651
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { normalize, basename, dirname, relative } from "node:path";
|
|
2
|
+
function toTitleCase(str) {
|
|
3
|
+
return str.replace(/\w\S*/g, (txt) => {
|
|
4
|
+
return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase();
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
function addError(ctx, e) {
|
|
8
|
+
ctx.diagnostics.push({
|
|
9
|
+
type: "error",
|
|
10
|
+
message: e ? String(e.stack || e) : "Error"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function addWarning(ctx, message) {
|
|
14
|
+
ctx.diagnostics.push({
|
|
15
|
+
type: "warn",
|
|
16
|
+
message: String(message)
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function msToString(ms) {
|
|
20
|
+
if (ms < 1) {
|
|
21
|
+
return ms.toFixed(2) + " ms";
|
|
22
|
+
}
|
|
23
|
+
if (ms < 1e3) {
|
|
24
|
+
return ms.toFixed(1) + " ms";
|
|
25
|
+
}
|
|
26
|
+
if (ms < 6e4) {
|
|
27
|
+
return (ms / 1e3).toFixed(1) + " s";
|
|
28
|
+
}
|
|
29
|
+
return (ms / 6e4).toFixed(1) + " m";
|
|
30
|
+
}
|
|
31
|
+
function normalizePathname(pathname, basePathname) {
|
|
32
|
+
if (typeof pathname === "string") {
|
|
33
|
+
pathname = pathname.trim();
|
|
34
|
+
if (pathname !== "") {
|
|
35
|
+
try {
|
|
36
|
+
pathname = pathname.replace(/\/+/g, "/");
|
|
37
|
+
if (pathname.startsWith("/")) {
|
|
38
|
+
pathname = pathname.slice(1);
|
|
39
|
+
}
|
|
40
|
+
pathname = new URL(basePathname + pathname, `https://qwik.dev`).pathname;
|
|
41
|
+
if (pathname !== basePathname) {
|
|
42
|
+
if (!globalThis.__NO_TRAILING_SLASH__) {
|
|
43
|
+
if (!pathname.endsWith("/")) {
|
|
44
|
+
const segments = pathname.split("/");
|
|
45
|
+
const lastSegment = segments[segments.length - 1];
|
|
46
|
+
if (!lastSegment.includes(".")) {
|
|
47
|
+
pathname += "/";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
if (pathname.endsWith("/")) {
|
|
52
|
+
pathname = pathname.slice(0, pathname.length - 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return pathname;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.error(e);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function getPathnameForDynamicRoute(originalPathname, paramNames, params) {
|
|
65
|
+
let pathname = originalPathname;
|
|
66
|
+
if (paramNames && params) {
|
|
67
|
+
for (const paramName of paramNames) {
|
|
68
|
+
const paramKey = `[${paramName}]`;
|
|
69
|
+
const restParamKey = `[...${paramName}]`;
|
|
70
|
+
const paramValue = params[paramName];
|
|
71
|
+
pathname = pathname.replace(restParamKey, paramValue);
|
|
72
|
+
pathname = pathname.replace(paramKey, paramValue);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return pathname;
|
|
76
|
+
}
|
|
77
|
+
function isSameOriginUrl(url) {
|
|
78
|
+
if (typeof url === "string") {
|
|
79
|
+
url = url.trim();
|
|
80
|
+
if (url !== "") {
|
|
81
|
+
const firstChar = url.charAt(0);
|
|
82
|
+
if (firstChar !== "/" && firstChar !== ".") {
|
|
83
|
+
if (firstChar === "#") {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const i = url.indexOf(":");
|
|
87
|
+
if (i > -1) {
|
|
88
|
+
const protocol = url.slice(0, i).toLowerCase();
|
|
89
|
+
return !PROTOCOLS[protocol];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const PROTOCOLS = {
|
|
98
|
+
https: true,
|
|
99
|
+
http: true,
|
|
100
|
+
about: true,
|
|
101
|
+
javascript: true,
|
|
102
|
+
file: true
|
|
103
|
+
};
|
|
104
|
+
function parseRouteIndexName(extlessName) {
|
|
105
|
+
let layoutName = "";
|
|
106
|
+
const layoutStop = extlessName.endsWith("!");
|
|
107
|
+
if (layoutStop) {
|
|
108
|
+
extlessName = extlessName.slice(0, extlessName.length - 1);
|
|
109
|
+
}
|
|
110
|
+
const namedLayoutParts = extlessName.split("@");
|
|
111
|
+
if (namedLayoutParts.length > 1) {
|
|
112
|
+
namedLayoutParts.shift();
|
|
113
|
+
layoutName = namedLayoutParts.join("@");
|
|
114
|
+
}
|
|
115
|
+
return { layoutName, layoutStop };
|
|
116
|
+
}
|
|
117
|
+
function getPathnameFromDirPath(opts, dirPath) {
|
|
118
|
+
const relFilePath = relative(opts.routesDir, dirPath);
|
|
119
|
+
let pathname = normalizePath(relFilePath);
|
|
120
|
+
pathname = normalizePathname(pathname, opts.basePathname).split("/").filter((segment) => !isGroupedLayoutName(segment)).join("/");
|
|
121
|
+
if (pathname === "") {
|
|
122
|
+
return "/";
|
|
123
|
+
}
|
|
124
|
+
return pathname;
|
|
125
|
+
}
|
|
126
|
+
function getMenuPathname(opts, filePath) {
|
|
127
|
+
let pathname = normalizePath(relative(opts.routesDir, filePath));
|
|
128
|
+
pathname = `/` + normalizePath(dirname(pathname));
|
|
129
|
+
let result = normalizePathname(pathname, opts.basePathname);
|
|
130
|
+
if (!result.endsWith("/")) {
|
|
131
|
+
result += "/";
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
function getExtension(fileName) {
|
|
136
|
+
if (typeof fileName === "string") {
|
|
137
|
+
const parts = fileName.trim().toLowerCase().split(".");
|
|
138
|
+
if (parts.length > 1) {
|
|
139
|
+
const ext = parts.pop().split("?")[0].split("#")[0];
|
|
140
|
+
if (ext === "ts" && parts.pop() === "d") {
|
|
141
|
+
return ".d.ts";
|
|
142
|
+
}
|
|
143
|
+
return "." + ext;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
148
|
+
function removeExtension(fileName) {
|
|
149
|
+
if (typeof fileName === "string") {
|
|
150
|
+
fileName = fileName.trim();
|
|
151
|
+
const ext = getExtension(fileName);
|
|
152
|
+
return fileName.slice(0, fileName.length - ext.length);
|
|
153
|
+
}
|
|
154
|
+
return "";
|
|
155
|
+
}
|
|
156
|
+
function normalizePath(path) {
|
|
157
|
+
return normalizePathSlash(normalize(path));
|
|
158
|
+
}
|
|
159
|
+
function normalizePathSlash(path) {
|
|
160
|
+
const isExtendedLengthPath = path.startsWith("\\\\?\\");
|
|
161
|
+
const hasNonAscii = /[^\u0000-\u0080]+/.test(path);
|
|
162
|
+
if (isExtendedLengthPath || hasNonAscii) {
|
|
163
|
+
return path;
|
|
164
|
+
}
|
|
165
|
+
path = path.replace(/\\/g, "/");
|
|
166
|
+
if (path.endsWith("/")) {
|
|
167
|
+
path = path.slice(0, path.length - 1);
|
|
168
|
+
}
|
|
169
|
+
return path;
|
|
170
|
+
}
|
|
171
|
+
function createFileId(routesDir, fsPath, explicitFileType) {
|
|
172
|
+
const ids = [];
|
|
173
|
+
for (let i = 0; i < 25; i++) {
|
|
174
|
+
let baseName = removeExtension(basename(fsPath));
|
|
175
|
+
baseName = baseName.replace(/[\W_]+/g, "");
|
|
176
|
+
if (baseName === "") {
|
|
177
|
+
baseName = "Q" + i;
|
|
178
|
+
} else if (!isNaN(baseName.charAt(0))) {
|
|
179
|
+
baseName = "Q" + baseName;
|
|
180
|
+
}
|
|
181
|
+
ids.push(toTitleCase(baseName));
|
|
182
|
+
fsPath = normalizePath(dirname(fsPath));
|
|
183
|
+
if (fsPath === routesDir) {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (ids.length > 1 && ids[0] === "Index") {
|
|
188
|
+
ids.shift();
|
|
189
|
+
}
|
|
190
|
+
return ids.reverse().join("").concat(explicitFileType || "");
|
|
191
|
+
}
|
|
192
|
+
const PAGE_MODULE_EXTS = {
|
|
193
|
+
".tsx": true,
|
|
194
|
+
".jsx": true
|
|
195
|
+
};
|
|
196
|
+
const MODULE_EXTS = {
|
|
197
|
+
".ts": true,
|
|
198
|
+
".js": true
|
|
199
|
+
};
|
|
200
|
+
const MARKDOWN_EXTS = {
|
|
201
|
+
".md": true,
|
|
202
|
+
".mdx": true
|
|
203
|
+
};
|
|
204
|
+
function isIndexModule(extlessName) {
|
|
205
|
+
return /^index(|!|@.+)$/.test(extlessName);
|
|
206
|
+
}
|
|
207
|
+
function isPluginModule(extlessName) {
|
|
208
|
+
return /^plugin(|@.+)$/.test(extlessName);
|
|
209
|
+
}
|
|
210
|
+
function isLayoutModule(extlessName) {
|
|
211
|
+
return /^layout(|!|-.+)$/.test(extlessName);
|
|
212
|
+
}
|
|
213
|
+
function isPageModuleExt(ext) {
|
|
214
|
+
return ext in PAGE_MODULE_EXTS;
|
|
215
|
+
}
|
|
216
|
+
function isModuleExt(ext) {
|
|
217
|
+
return ext in MODULE_EXTS;
|
|
218
|
+
}
|
|
219
|
+
function isMarkdownExt(ext) {
|
|
220
|
+
return ext in MARKDOWN_EXTS;
|
|
221
|
+
}
|
|
222
|
+
function isPageExt(ext) {
|
|
223
|
+
return ext in PAGE_MODULE_EXTS || ext in MARKDOWN_EXTS;
|
|
224
|
+
}
|
|
225
|
+
function isMenuFileName(fileName) {
|
|
226
|
+
return fileName === "menu.md";
|
|
227
|
+
}
|
|
228
|
+
function isServiceWorkerName(extlessName) {
|
|
229
|
+
return extlessName === "service-worker";
|
|
230
|
+
}
|
|
231
|
+
function isEntryName(extlessName) {
|
|
232
|
+
return extlessName === "entry";
|
|
233
|
+
}
|
|
234
|
+
function isErrorName(extlessName) {
|
|
235
|
+
return /^[45][0-9]{2}$/.test(extlessName);
|
|
236
|
+
}
|
|
237
|
+
function isGroupedLayoutName(dirName, warn = true) {
|
|
238
|
+
if (dirName.startsWith("__")) {
|
|
239
|
+
if (warn) {
|
|
240
|
+
console.warn(
|
|
241
|
+
`Grouped (pathless) layout "${dirName}" should use the "(${dirName.slice(
|
|
242
|
+
2
|
|
243
|
+
)})" directory name instead. Prefixing a directory with "__" has been deprecated and will be removed in future versions.`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
return dirName.startsWith("(") && dirName.endsWith(")");
|
|
249
|
+
}
|
|
250
|
+
export {
|
|
251
|
+
isErrorName as a,
|
|
252
|
+
isLayoutModule as b,
|
|
253
|
+
isEntryName as c,
|
|
254
|
+
isMenuFileName as d,
|
|
255
|
+
isServiceWorkerName as e,
|
|
256
|
+
isPageModuleExt as f,
|
|
257
|
+
getExtension as g,
|
|
258
|
+
isModuleExt as h,
|
|
259
|
+
isIndexModule as i,
|
|
260
|
+
isMarkdownExt as j,
|
|
261
|
+
isSameOriginUrl as k,
|
|
262
|
+
normalizePath as l,
|
|
263
|
+
getPathnameFromDirPath as m,
|
|
264
|
+
normalizePathSlash as n,
|
|
265
|
+
getMenuPathname as o,
|
|
266
|
+
createFileId as p,
|
|
267
|
+
parseRouteIndexName as q,
|
|
268
|
+
removeExtension as r,
|
|
269
|
+
isPluginModule as s,
|
|
270
|
+
addError as t,
|
|
271
|
+
addWarning as u,
|
|
272
|
+
isPageExt as v,
|
|
273
|
+
msToString as w,
|
|
274
|
+
getPathnameForDynamicRoute as x
|
|
275
|
+
};
|