nuxt-i18n-micro 1.99.0 → 1.100.1

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/dist/module.mjs CHANGED
@@ -110,95 +110,119 @@ function setupDevToolsUI(options, resolve2) {
110
110
  });
111
111
  }
112
112
 
113
- function extractDefineI18nRouteData(content, filePath) {
114
- const defineMatch = content.match(/\$?\bdefineI18nRoute\s*\(\s*\{[\s\S]*?\}\s*\)/);
115
- if (!defineMatch) {
116
- return { locales: null, localeRoutes: null };
117
- }
118
- const defineContent = defineMatch[0];
119
- let locales = null;
120
- let localeRoutes = null;
121
- let localesStr = "";
122
- const localesStart = defineContent.indexOf("locales:");
123
- if (localesStart !== -1) {
124
- const afterLocales = defineContent.substring(localesStart + 8);
125
- const trimmed = afterLocales.trim();
126
- if (trimmed.startsWith("[")) {
127
- let bracketCount = 0;
128
- let i = 0;
129
- for (; i < trimmed.length; i++) {
130
- if (trimmed[i] === "[") bracketCount++;
131
- if (trimmed[i] === "]") bracketCount--;
132
- if (bracketCount === 0) break;
133
- }
134
- localesStr = trimmed.substring(0, i + 1);
135
- } else if (trimmed.startsWith("{")) {
136
- let braceCount = 0;
137
- let i = 0;
138
- for (; i < trimmed.length; i++) {
139
- if (trimmed[i] === "{") braceCount++;
140
- if (trimmed[i] === "}") braceCount--;
141
- if (braceCount === 0) break;
142
- }
143
- localesStr = trimmed.substring(0, i + 1);
113
+ function extractScriptContent(content) {
114
+ const scriptMatch = content.match(/<script[^>]*>([\s\S]*?)<\/script>/);
115
+ return scriptMatch ? scriptMatch[1] : null;
116
+ }
117
+ function removeTypeScriptTypes(scriptContent) {
118
+ return scriptContent.replace(/\((\w+):[^)]*\)/g, "($1)");
119
+ }
120
+ function findDefineI18nRouteConfig(scriptContent) {
121
+ try {
122
+ const defineStart = scriptContent.indexOf("$defineI18nRoute(");
123
+ if (defineStart === -1) {
124
+ return null;
144
125
  }
145
- }
146
- if (localesStr) {
147
- try {
148
- const localesStrTrimmed = localesStr.trim();
149
- if (localesStrTrimmed.startsWith("[") && localesStrTrimmed.endsWith("]")) {
150
- const arrayMatch = localesStrTrimmed.match(/\[(.*?)\]/s);
151
- if (arrayMatch && arrayMatch[1]) {
152
- const elements = arrayMatch[1].split(",").map((el) => el.trim().replace(/['"]/g, "")).filter((el) => el.length > 0);
153
- locales = elements;
154
- }
155
- }
156
- if (localesStrTrimmed.startsWith("{") && localesStrTrimmed.endsWith("}")) {
157
- const topLevelKeyMatches = localesStrTrimmed.match(/^\s*(\w+)\s*:\s*\{/gm);
158
- if (topLevelKeyMatches) {
159
- const keys = topLevelKeyMatches.map((match) => {
160
- const keyMatch = match.match(/^\s*(\w+)\s*:/);
161
- return keyMatch ? keyMatch[1] : "";
162
- }).filter((key) => key.length > 0);
163
- locales = keys;
164
- } else {
165
- const fallbackMatches = localesStrTrimmed.match(/(\w+)\s*:\s*\{/g);
166
- if (fallbackMatches) {
167
- const keys = fallbackMatches.map((match) => {
168
- const keyMatch = match.match(/(\w+)\s*:/);
169
- return keyMatch ? keyMatch[1] : "";
170
- }).filter((key) => key.length > 0);
171
- locales = keys;
172
- }
173
- }
126
+ const openParen = scriptContent.indexOf("(", defineStart);
127
+ if (openParen === -1) {
128
+ return null;
129
+ }
130
+ let braceCount = 0;
131
+ let parenCount = 1;
132
+ let i = openParen + 1;
133
+ for (; i < scriptContent.length; i++) {
134
+ if (scriptContent[i] === "{") braceCount++;
135
+ if (scriptContent[i] === "}") braceCount--;
136
+ if (scriptContent[i] === "(") parenCount++;
137
+ if (scriptContent[i] === ")") {
138
+ parenCount--;
139
+ if (parenCount === 0 && braceCount === 0) break;
174
140
  }
175
- } catch (error) {
176
- console.error("Failed to parse locales:", error, "in file:", filePath);
177
141
  }
178
- }
179
- const localeRoutesMatch = defineContent.match(/localeRoutes:\s*(\{[\s\S]*?\})/);
180
- if (localeRoutesMatch && localeRoutesMatch[1]) {
142
+ if (i >= scriptContent.length) {
143
+ return null;
144
+ }
145
+ const configStr = scriptContent.substring(openParen + 1, i);
181
146
  try {
182
- const parsedLocaleRoutes = Function('"use strict";return (' + localeRoutesMatch[1] + ")")();
183
- if (typeof parsedLocaleRoutes === "object" && parsedLocaleRoutes !== null) {
184
- if (validateDefineI18nRouteConfig(parsedLocaleRoutes)) {
185
- localeRoutes = parsedLocaleRoutes;
147
+ const cleanConfigStr = removeTypeScriptTypes(configStr);
148
+ try {
149
+ const configObject = Function('"use strict";return (' + cleanConfigStr + ")")();
150
+ try {
151
+ const serialized = JSON.stringify(configObject);
152
+ return JSON.parse(serialized);
153
+ } catch {
154
+ return configObject;
155
+ }
156
+ } catch {
157
+ const scriptWithoutImports = scriptContent.split("\n").filter((line) => !line.trim().startsWith("import ")).join("\n");
158
+ const cleanScript = removeTypeScriptTypes(scriptWithoutImports);
159
+ const safeScript = `
160
+ // Mock $defineI18nRoute to prevent errors
161
+ const $defineI18nRoute = () => {}
162
+ const defineI18nRoute = () => {}
163
+
164
+ // Mock process.env for conditional logic
165
+ const process = { env: { NODE_ENV: 'development' } }
166
+
167
+ // Execute the script content without imports and TypeScript types
168
+ ${cleanScript}
169
+
170
+ // Return the config object
171
+ return (${cleanConfigStr})
172
+ `;
173
+ const configObject = Function('"use strict";' + safeScript)();
174
+ try {
175
+ const serialized = JSON.stringify(configObject);
176
+ return JSON.parse(serialized);
177
+ } catch {
178
+ return configObject;
186
179
  }
187
- } else {
188
- console.error("localeRoutes found but it is not a valid object in file:", filePath);
189
180
  }
190
- } catch (error) {
191
- console.error("Failed to parse localeRoutes:", error, "in file:", filePath);
181
+ } catch {
182
+ return null;
192
183
  }
184
+ } catch {
185
+ return null;
193
186
  }
194
- return { locales, localeRoutes };
195
187
  }
196
- function validateDefineI18nRouteConfig(obj) {
197
- if (typeof obj !== "object") return false;
198
- for (const routeKey in obj.localeRoutes) {
199
- if (typeof obj.localeRoutes[routeKey] !== "string") return false;
188
+ function extractDefineI18nRouteData(content, _filePath) {
189
+ try {
190
+ const scriptContent = extractScriptContent(content);
191
+ if (!scriptContent) {
192
+ return { locales: null, localeRoutes: null };
193
+ }
194
+ const configObject = findDefineI18nRouteConfig(scriptContent);
195
+ if (!configObject) {
196
+ return { locales: null, localeRoutes: null };
197
+ }
198
+ let locales = null;
199
+ if (configObject.locales) {
200
+ if (Array.isArray(configObject.locales)) {
201
+ locales = configObject.locales.map((item) => {
202
+ if (typeof item === "string") {
203
+ return item;
204
+ } else if (typeof item === "object" && item !== null && item.code) {
205
+ return item.code;
206
+ }
207
+ return null;
208
+ }).filter((item) => item !== null);
209
+ } else if (typeof configObject.locales === "object") {
210
+ locales = Object.keys(configObject.locales).filter(
211
+ (key) => key !== "meta" && key !== "path" && key !== "title" && key !== "description"
212
+ );
213
+ }
214
+ }
215
+ let localeRoutes = null;
216
+ if (configObject.localeRoutes && typeof configObject.localeRoutes === "object") {
217
+ const isValid = Object.values(configObject.localeRoutes).every((value) => typeof value === "string");
218
+ if (isValid) {
219
+ localeRoutes = configObject.localeRoutes;
220
+ }
221
+ }
222
+ return { locales, localeRoutes };
223
+ } catch {
224
+ return { locales: null, localeRoutes: null };
200
225
  }
201
- return true;
202
226
  }
203
227
  const normalizePath = (routePath) => {
204
228
  if (!routePath) {
@@ -240,9 +264,10 @@ class PageManager {
240
264
  activeLocaleCodes;
241
265
  globalLocaleRoutes;
242
266
  filesLocaleRoutes;
267
+ routeLocales;
243
268
  noPrefixRedirect;
244
269
  excludePatterns;
245
- constructor(locales, defaultLocaleCode, strategy, globalLocaleRoutes, filesLocaleRoutes, noPrefixRedirect, excludePatterns) {
270
+ constructor(locales, defaultLocaleCode, strategy, globalLocaleRoutes, filesLocaleRoutes, routeLocales, noPrefixRedirect, excludePatterns) {
246
271
  this.locales = locales;
247
272
  this.defaultLocale = this.findLocaleByCode(defaultLocaleCode) || { code: defaultLocaleCode };
248
273
  this.strategy = strategy;
@@ -251,6 +276,7 @@ class PageManager {
251
276
  this.activeLocaleCodes = this.computeActiveLocaleCodes();
252
277
  this.globalLocaleRoutes = globalLocaleRoutes || {};
253
278
  this.filesLocaleRoutes = filesLocaleRoutes || {};
279
+ this.routeLocales = routeLocales || {};
254
280
  }
255
281
  findLocaleByCode(code) {
256
282
  return this.locales.find((locale) => locale.code === code);
@@ -258,10 +284,22 @@ class PageManager {
258
284
  computeActiveLocaleCodes() {
259
285
  return this.locales.filter((locale) => locale.code !== this.defaultLocale.code || isPrefixAndDefaultStrategy(this.strategy) || isPrefixStrategy(this.strategy)).map((locale) => locale.code);
260
286
  }
287
+ getAllowedLocalesForPage(pagePath, pageName) {
288
+ const allowedLocales = this.routeLocales[pagePath] || this.routeLocales[pageName];
289
+ if (allowedLocales && allowedLocales.length > 0) {
290
+ return allowedLocales.filter(
291
+ (locale) => this.locales.some((l) => l.code === locale)
292
+ );
293
+ }
294
+ return this.locales.map((locale) => locale.code);
295
+ }
296
+ hasLocaleRestrictions(pagePath, pageName) {
297
+ return !!(this.routeLocales[pagePath] || this.routeLocales[pageName]);
298
+ }
261
299
  // private isAlreadyLocalized(p: string) {
262
300
  // const codes = this.locales.map(l => l.code).join('|') // en|de|ru…
263
- // return p.startsWith('/:locale(') // динамический префикс
264
- // || new RegExp(`^/(${codes})(/|$)`).test(p) // статический /de/…
301
+ // return p.startsWith('/:locale(') // dynamic prefix
302
+ // || new RegExp(`^/(${codes})(/|$)`).test(p) // static /de/…
265
303
  // }
266
304
  extendPages(pages, customRegex, isCloudflarePages) {
267
305
  this.localizedPaths = this.extractLocalizedPaths(pages);
@@ -302,15 +340,14 @@ class PageManager {
302
340
  const localizedPaths = {};
303
341
  pages.forEach((page) => {
304
342
  const pageName = buildRouteNameFromRoute(page.name, page.path);
305
- const globalLocalePath = this.globalLocaleRoutes[pageName];
343
+ const normalizedFullPath = normalizePath(path.posix.join(parentPath, page.path));
344
+ const globalLocalePath = this.globalLocaleRoutes[normalizedFullPath] || this.globalLocaleRoutes[pageName];
306
345
  if (!globalLocalePath) {
307
346
  const filesLocalePath = this.filesLocaleRoutes[pageName];
308
347
  if (filesLocalePath && typeof filesLocalePath === "object") {
309
- const normalizedFullPath = normalizePath(path.posix.join(parentPath, page.path));
310
348
  localizedPaths[normalizedFullPath] = filesLocalePath;
311
349
  }
312
350
  } else if (typeof globalLocalePath === "object") {
313
- const normalizedFullPath = normalizePath(path.posix.join(parentPath, page.path));
314
351
  localizedPaths[normalizedFullPath] = globalLocalePath;
315
352
  }
316
353
  if (page.children?.length) {
@@ -321,7 +358,12 @@ class PageManager {
321
358
  return localizedPaths;
322
359
  }
323
360
  addCustomGlobalLocalizedRoutes(page, customRoutePaths, additionalRoutes, customRegex) {
324
- this.locales.forEach((locale) => {
361
+ const normalizedFullPath = normalizePath(page.path);
362
+ const pageName = buildRouteNameFromRoute(page.name, page.path);
363
+ const allowedLocales = this.getAllowedLocalesForPage(normalizedFullPath, pageName);
364
+ const hasRestrictions = this.hasLocaleRestrictions(normalizedFullPath, pageName);
365
+ const localesToUse = hasRestrictions ? this.locales.filter((locale) => allowedLocales.includes(locale.code)) : this.locales;
366
+ localesToUse.forEach((locale) => {
325
367
  const customPath = customRoutePaths[locale.code];
326
368
  const isDefaultLocale = isLocaleDefault(locale, this.defaultLocale, isPrefixStrategy(this.strategy) || isPrefixAndDefaultStrategy(this.strategy));
327
369
  if (customPath) {
@@ -353,17 +395,44 @@ class PageManager {
353
395
  if (isPageRedirectOnly(page)) return;
354
396
  const originalChildren = cloneArray(page.children ?? []);
355
397
  const normalizedFullPath = normalizePath(page.path);
356
- const localeCodesWithoutCustomPaths = this.filterLocaleCodesWithoutCustomPaths(normalizedFullPath);
398
+ const pageName = buildRouteNameFromRoute(page.name, page.path);
399
+ const allowedLocales = this.getAllowedLocalesForPage(normalizedFullPath, pageName);
400
+ const hasRestrictions = this.hasLocaleRestrictions(normalizedFullPath, pageName);
401
+ const localeCodesWithoutCustomPaths = this.filterLocaleCodesWithoutCustomPaths(normalizedFullPath).filter((locale) => hasRestrictions ? allowedLocales.includes(locale) : true);
357
402
  if (localeCodesWithoutCustomPaths.length) {
358
403
  const newRoute = this.createLocalizedRoute(page, localeCodesWithoutCustomPaths, originalChildren, false, "", customRegex, false, true);
359
404
  if (newRoute) additionalRoutes.push(newRoute);
360
405
  }
361
- this.addCustomLocalizedRoutes(page, normalizedFullPath, originalChildren, additionalRoutes);
406
+ this.addCustomLocalizedRoutes(page, normalizedFullPath, originalChildren, additionalRoutes, hasRestrictions ? allowedLocales : void 0);
362
407
  this.adjustRouteForDefaultLocale(page, originalChildren);
408
+ this.handleAliasRoutes(page, additionalRoutes, customRegex, hasRestrictions ? allowedLocales : void 0);
363
409
  }
364
410
  filterLocaleCodesWithoutCustomPaths(fullPath) {
365
411
  return this.activeLocaleCodes.filter((code) => !this.localizedPaths[fullPath]?.[code]);
366
412
  }
413
+ handleAliasRoutes(page, additionalRoutes, customRegex, allowedLocales) {
414
+ const aliasRoutes = page.alias || page.meta?.alias;
415
+ if (!aliasRoutes || !Array.isArray(aliasRoutes)) {
416
+ return;
417
+ }
418
+ const localesToUse = allowedLocales || this.activeLocaleCodes;
419
+ aliasRoutes.forEach((aliasPath) => {
420
+ const localizedAliasPath = buildFullPath(localesToUse, aliasPath, customRegex);
421
+ const aliasRoute = {
422
+ ...page,
423
+ path: localizedAliasPath,
424
+ name: `localized-${page.name ?? ""}`,
425
+ meta: {
426
+ ...page.meta,
427
+ alias: void 0
428
+ // Remove alias to prevent infinite recursion
429
+ },
430
+ alias: void 0
431
+ // Remove alias from root to prevent infinite recursion
432
+ };
433
+ additionalRoutes.push(aliasRoute);
434
+ });
435
+ }
367
436
  adjustRouteForDefaultLocale(page, originalChildren) {
368
437
  if (isNoPrefixStrategy(this.strategy)) {
369
438
  return;
@@ -397,16 +466,20 @@ class PageManager {
397
466
  page.children = currentChildren;
398
467
  }
399
468
  }
400
- addCustomLocalizedRoutes(page, fullPath, originalChildren, additionalRoutes, customRegex) {
401
- this.locales.forEach((locale) => {
469
+ addCustomLocalizedRoutes(page, fullPath, originalChildren, additionalRoutes, allowedLocales, customRegex) {
470
+ const localesToUse = allowedLocales ? this.locales.filter((locale) => allowedLocales.includes(locale.code)) : this.locales;
471
+ localesToUse.forEach((locale) => {
402
472
  const customPath = this.localizedPaths[fullPath]?.[locale.code];
403
473
  if (!customPath) return;
404
474
  const isDefaultLocale = isLocaleDefault(locale, this.defaultLocale, isPrefixStrategy(this.strategy) || isNoPrefixStrategy(this.strategy));
405
- if (isDefaultLocale) {
406
- page.children = this.createLocalizedChildren(originalChildren, "", [locale.code], false);
475
+ if (isDefaultLocale && isPrefixExceptDefaultStrategy(this.strategy)) {
476
+ page.path = normalizePath(customPath);
477
+ page.children = this.createLocalizedChildren(originalChildren, "", [locale.code], false, false, false, { [locale.code]: customPath });
407
478
  } else {
408
479
  const newRoute = this.createLocalizedRoute(page, [locale.code], originalChildren, true, customPath, customRegex, false, locale.code);
409
- if (newRoute) additionalRoutes.push(newRoute);
480
+ if (newRoute) {
481
+ additionalRoutes.push(newRoute);
482
+ }
410
483
  }
411
484
  if (isPrefixAndDefaultStrategy(this.strategy) && locale === this.defaultLocale) {
412
485
  const newRoute = this.createLocalizedRoute(page, [locale.code], originalChildren, true, customPath, customRegex, true, locale.code);
@@ -430,7 +503,14 @@ class PageManager {
430
503
  createLocalizedVariants(route, parentPath, localeCodes, modifyName, addLocalePrefix, parentLocale = false, localizedParentPaths) {
431
504
  const routePath = normalizePath(route.path);
432
505
  const fullPath = normalizePath(path.posix.join(parentPath, routePath));
433
- const customLocalePaths = this.localizedPaths[fullPath] ?? this.localizedPaths[normalizePath(route.path)];
506
+ let customLocalePaths = this.localizedPaths[fullPath] ?? this.localizedPaths[normalizePath(route.path)];
507
+ if (!customLocalePaths && Object.keys(localizedParentPaths).length > 0) {
508
+ const hasLocalizedContext = Object.values(localizedParentPaths).some((path2) => path2 && path2 !== "");
509
+ if (hasLocalizedContext) {
510
+ const originalRoutePath = normalizePath(path.posix.join("/activity-locale", route.path));
511
+ customLocalePaths = this.localizedPaths[originalRoutePath];
512
+ }
513
+ }
434
514
  const isCustomLocalized = !!customLocalePaths;
435
515
  const result = [];
436
516
  if (!isCustomLocalized) {
@@ -457,15 +537,21 @@ class PageManager {
457
537
  const parentLocalizedPath = localizedParentPaths?.[locale];
458
538
  const hasParentLocalized = !!parentLocalizedPath;
459
539
  const customPath = customLocalePaths?.[locale];
460
- const basePath = customPath ? normalizePath(customPath) : normalizePath(route.path);
540
+ let basePath = customPath ? normalizePath(customPath) : normalizePath(route.path);
541
+ if (hasParentLocalized && parentLocalizedPath) {
542
+ if (customPath) {
543
+ basePath = normalizePath(customPath);
544
+ } else {
545
+ basePath = normalizePath(path.posix.join(parentLocalizedPath, route.path));
546
+ }
547
+ }
461
548
  const finalRoutePath = shouldAddLocalePrefix(
462
549
  locale,
463
550
  this.defaultLocale,
464
551
  addLocalePrefix,
465
552
  isPrefixStrategy(this.strategy)
466
553
  ) ? buildFullPath(locale, basePath) : basePath;
467
- const isChildRoute = parentPath !== "";
468
- const finalPathForRoute = isChildRoute && hasParentLocalized ? normalizePath(route.path) : removeLeadingSlash(finalRoutePath);
554
+ const finalPathForRoute = removeLeadingSlash(finalRoutePath);
469
555
  const nextParentPath = customPath ? normalizePath(customPath) : hasParentLocalized ? parentLocalizedPath : normalizePath(path.posix.join(parentPath, routePath));
470
556
  const localizedChildren = this.createLocalizedChildren(
471
557
  cloneArray(route.children ?? []),
@@ -512,7 +598,7 @@ class PageManager {
512
598
  const routeName = buildRouteName(buildRouteNameFromRoute(page.name ?? "", page.path ?? ""), firstLocale, isCustom);
513
599
  return {
514
600
  ...page,
515
- children: this.createLocalizedChildren(originalChildren, page.path, localeCodes, true, false, parentLocale),
601
+ children: this.createLocalizedChildren(originalChildren, page.path, localeCodes, true, false, parentLocale, { [firstLocale]: customPath }),
516
602
  path: routePath,
517
603
  name: routeName
518
604
  };
@@ -670,17 +756,17 @@ const module = defineNuxtModule({
670
756
  const fileContent = readFileSync(fullPath, "utf-8");
671
757
  const { locales: extractedLocales, localeRoutes } = extractDefineI18nRouteData(fileContent, fullPath);
672
758
  const routePath = pageFile.replace(/^pages\//, "/").replace(/\/index\.vue$/, "").replace(/\.vue$/, "").replace(/\/$/, "") || "/";
673
- const pageName = routePath.replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, "");
674
759
  if (extractedLocales) {
675
760
  routeLocales[routePath] = extractedLocales;
676
761
  }
677
762
  if (localeRoutes) {
678
- globalLocaleRoutes[pageName] = localeRoutes;
763
+ globalLocaleRoutes[routePath] = localeRoutes;
679
764
  }
680
765
  } catch {
681
766
  }
682
767
  }
683
- const pageManager = new PageManager(localeManager.locales, defaultLocale, options.strategy, options.globalLocaleRoutes, globalLocaleRoutes, options.noPrefixRedirect, options.excludePatterns);
768
+ const mergedGlobalLocaleRoutes = { ...options.globalLocaleRoutes, ...globalLocaleRoutes };
769
+ const pageManager = new PageManager(localeManager.locales, defaultLocale, options.strategy, mergedGlobalLocaleRoutes, globalLocaleRoutes, routeLocales, options.noPrefixRedirect, options.excludePatterns);
684
770
  addTemplate({
685
771
  filename: "i18n.plural.mjs",
686
772
  write: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
- "version": "1.99.0",
3
+ "version": "1.100.1",
4
4
  "description": "Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.",
5
5
  "repository": "s00d/nuxt-i18n-micro",
6
6
  "license": "MIT",
@@ -62,8 +62,8 @@
62
62
  "sirv": "^2.0.4",
63
63
  "ufo": "^1.5.4",
64
64
  "nuxt-i18n-micro-core": "1.0.18",
65
- "nuxt-i18n-micro-types": "1.0.9",
66
- "nuxt-i18n-micro-test-utils": "1.0.6"
65
+ "nuxt-i18n-micro-test-utils": "1.0.6",
66
+ "nuxt-i18n-micro-types": "1.0.9"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@nuxt/devtools": "^2.6.3",
@@ -1 +0,0 @@
1
- {"id":"ca54293c-61c3-4dc3-92ac-0c137374a55e","timestamp":1759737253768,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}