@decantr/verifier 3.5.0 → 3.5.4
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/index.js +57 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2363,6 +2363,8 @@ var STYLE_EXTENSIONS = /* @__PURE__ */ new Set([".css", ".scss", ".sass", ".less
|
|
|
2363
2363
|
var PAGE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte", ".html"]);
|
|
2364
2364
|
var ROUTE_VARIABLE_NAMES = "(?:path|pathname|route|currentPath|currentRoute|locationPath|activePath)";
|
|
2365
2365
|
var ROUTE_ASSET_EXTENSION_RE = /\.(?:avif|bmp|css|gif|ico|jpeg|jpg|js|json|map|mp4|pdf|png|svg|webp|woff2?)$/i;
|
|
2366
|
+
var JSX_ROUTE_PATH_RE = /<(?:Route|[A-Z][\w.]*Route)\b[^>]*\bpath\s*=\s*(?:"([^"]+)"|'([^']+)'|{\s*"([^"]+)"\s*}|{\s*'([^']+)'\s*}|{\s*`([^`]+)`\s*})/g;
|
|
2367
|
+
var OBJECT_ROUTE_PATH_RE = /\bpath\s*:\s*(?:"([^"]+)"|'([^']+)'|`([^`]+)`)/g;
|
|
2366
2368
|
var MAX_FILE_READ_BYTES = 512 * 1024;
|
|
2367
2369
|
var MAX_WALK_FILES = 5e3;
|
|
2368
2370
|
var MAX_REPORT_ROUTES = 80;
|
|
@@ -2629,9 +2631,12 @@ function fileRouteFromPath(file, baseDir) {
|
|
|
2629
2631
|
function scanFileRoutes(projectRoot, baseDir, extensions = PAGE_EXTENSIONS) {
|
|
2630
2632
|
const fullBase = join3(projectRoot, baseDir);
|
|
2631
2633
|
if (!existsSync3(fullBase)) return [];
|
|
2632
|
-
return walkFiles(fullBase, { extensions }).
|
|
2634
|
+
return walkFiles(fullBase, { extensions }).flatMap((file) => {
|
|
2635
|
+
const baseName = file.split("/").pop() ?? file;
|
|
2636
|
+
const routeFileName = baseName.slice(0, -extname3(baseName).length);
|
|
2637
|
+
if (routeFileName.startsWith("_")) return [];
|
|
2633
2638
|
const rel = relative3(projectRoot, join3(fullBase, file)).replace(/\\/g, "/");
|
|
2634
|
-
return { path: fileRouteFromPath(rel, baseDir), file: rel, hasLayout: false };
|
|
2639
|
+
return [{ path: fileRouteFromPath(rel, baseDir), file: rel, hasLayout: false }];
|
|
2635
2640
|
});
|
|
2636
2641
|
}
|
|
2637
2642
|
function scanReactRouter(projectRoot) {
|
|
@@ -2642,37 +2647,57 @@ function scanReactRouter(projectRoot) {
|
|
|
2642
2647
|
const content = readTextFile(join3(projectRoot, file));
|
|
2643
2648
|
if (!content) continue;
|
|
2644
2649
|
if (content.includes("HashRouter") || content.includes("createHashRouter")) hashRouting = true;
|
|
2645
|
-
const
|
|
2646
|
-
|
|
2647
|
-
const route
|
|
2648
|
-
|
|
2650
|
+
for (const match of content.matchAll(JSX_ROUTE_PATH_RE)) {
|
|
2651
|
+
const literal = firstRouteLiteralMatch(match);
|
|
2652
|
+
for (const route of normalizeDetectedRouteLiterals(literal || "/")) {
|
|
2653
|
+
routes.set(route, { path: route, file, hasLayout: false });
|
|
2654
|
+
}
|
|
2649
2655
|
}
|
|
2650
|
-
const
|
|
2651
|
-
|
|
2652
|
-
const route
|
|
2653
|
-
|
|
2656
|
+
for (const match of content.matchAll(OBJECT_ROUTE_PATH_RE)) {
|
|
2657
|
+
const literal = firstRouteLiteralMatch(match);
|
|
2658
|
+
for (const route of normalizeDetectedRouteLiterals(literal || "/")) {
|
|
2659
|
+
routes.set(route, { path: route, file, hasLayout: false });
|
|
2660
|
+
}
|
|
2654
2661
|
}
|
|
2655
2662
|
for (const route of detectPathnameBranchRoutes(content)) {
|
|
2656
2663
|
routes.set(route, { path: route, file, hasLayout: false });
|
|
2657
2664
|
}
|
|
2665
|
+
for (const route of detectDeclarativeRouteSpecRoutes(content)) {
|
|
2666
|
+
routes.set(route, { path: route, file, hasLayout: false });
|
|
2667
|
+
}
|
|
2658
2668
|
}
|
|
2659
2669
|
return { routes: [...routes.values()], hashRouting };
|
|
2660
2670
|
}
|
|
2661
|
-
function
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2671
|
+
function firstRouteLiteralMatch(match) {
|
|
2672
|
+
return match.slice(1).find((value) => typeof value === "string") ?? null;
|
|
2673
|
+
}
|
|
2674
|
+
function normalizeDetectedRouteLiterals(value) {
|
|
2675
|
+
const withoutHash = value.trim().split("#")[0];
|
|
2676
|
+
const cleaned = withoutHash.includes("?") && !withoutHash.endsWith(")?") ? withoutHash.split("?")[0] : withoutHash;
|
|
2677
|
+
if (!cleaned || cleaned === "/") return ["/"];
|
|
2678
|
+
if (cleaned === "*" || cleaned === "**" || cleaned.startsWith("#")) return [];
|
|
2679
|
+
if (cleaned === "/*" || cleaned === "/**") return [];
|
|
2680
|
+
if (!cleaned.startsWith("/") || cleaned.startsWith("//")) return [];
|
|
2681
|
+
if (ROUTE_ASSET_EXTENSION_RE.test(cleaned)) return [];
|
|
2682
|
+
const optionalGroup = cleaned.match(/^\/\(([^()]+)\)\?$/);
|
|
2683
|
+
if (optionalGroup) {
|
|
2684
|
+
return [
|
|
2685
|
+
"/",
|
|
2686
|
+
...optionalGroup[1].split("|").map((segment) => segment.trim()).filter(Boolean).map((segment) => `/${segment}`)
|
|
2687
|
+
];
|
|
2688
|
+
}
|
|
2689
|
+
const withoutTrailingWildcard = cleaned.endsWith("*") && !cleaned.endsWith("/*") && !/:\w+\*$/.test(cleaned) ? cleaned.slice(0, -1) : cleaned;
|
|
2690
|
+
const normalized = withoutTrailingWildcard.replace(/\/+$/g, "") || "/";
|
|
2691
|
+
if (normalized === "/*" || normalized === "/**") return [];
|
|
2692
|
+
return [normalized];
|
|
2668
2693
|
}
|
|
2669
2694
|
function collectRouteLiterals(pattern, content, routes) {
|
|
2670
2695
|
let count = 0;
|
|
2671
2696
|
for (const match of content.matchAll(pattern)) {
|
|
2672
|
-
const route
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2697
|
+
for (const route of normalizeDetectedRouteLiterals(match[1] ?? "")) {
|
|
2698
|
+
routes.add(route);
|
|
2699
|
+
count += 1;
|
|
2700
|
+
}
|
|
2676
2701
|
}
|
|
2677
2702
|
return count;
|
|
2678
2703
|
}
|
|
@@ -2695,6 +2720,17 @@ function detectPathnameBranchRoutes(content) {
|
|
|
2695
2720
|
}
|
|
2696
2721
|
return [...routes];
|
|
2697
2722
|
}
|
|
2723
|
+
function detectDeclarativeRouteSpecRoutes(content) {
|
|
2724
|
+
const routes = /* @__PURE__ */ new Set();
|
|
2725
|
+
const hasRouteSpecSignal = content.includes("@wasp.sh/spec") || /\b(?:const|export\s+const)\s+\w*Spec\b/.test(content) || /\bapp\s*\(\s*\{[\s\S]*\bspec\s*:/.test(content);
|
|
2726
|
+
if (!hasRouteSpecSignal) return [];
|
|
2727
|
+
collectRouteLiterals(
|
|
2728
|
+
/\broute\s*\(\s*["'`][^"'`]*["'`]\s*,\s*["'`](\/[^"'`]*)["'`]\s*,\s*page\s*\(/g,
|
|
2729
|
+
content,
|
|
2730
|
+
routes
|
|
2731
|
+
);
|
|
2732
|
+
return [...routes];
|
|
2733
|
+
}
|
|
2698
2734
|
function scanRoutes(projectRoot, detection) {
|
|
2699
2735
|
const appRoutes = ["src/app", "app"].flatMap(
|
|
2700
2736
|
(dir) => existsSync3(join3(projectRoot, dir)) ? walkNextAppRoutes(join3(projectRoot, dir), projectRoot, []) : []
|