shokupan 0.10.4 → 0.10.5
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.cjs +71 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +71 -29
- package/dist/index.js.map +1 -1
- package/dist/plugins/application/api-explorer/static/explorer-client.mjs +48 -1
- package/dist/plugins/application/api-explorer/static/style.css +25 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1083,7 +1083,7 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1083
1083
|
astRoutes = await getAstRoutes$1(applications);
|
|
1084
1084
|
} catch (e) {
|
|
1085
1085
|
}
|
|
1086
|
-
const collect = (router, prefix = "", currentGroup = defaultTagGroup, defaultTag = defaultTagName, inheritedMiddleware = []) => {
|
|
1086
|
+
const collect = (router, prefix = "", currentGroup = defaultTagGroup, defaultTag = defaultTagName, inheritedMiddleware = [], isRootLevel = true) => {
|
|
1087
1087
|
let group = currentGroup;
|
|
1088
1088
|
let tag = defaultTag;
|
|
1089
1089
|
if (router.config?.group) group = router.config.group;
|
|
@@ -1091,7 +1091,7 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1091
1091
|
tag = router.config.name;
|
|
1092
1092
|
} else {
|
|
1093
1093
|
const mountPath = router[$mountPath];
|
|
1094
|
-
if (mountPath && mountPath !== "/") {
|
|
1094
|
+
if (isRootLevel && mountPath && mountPath !== "/") {
|
|
1095
1095
|
const segments = mountPath.split("/").filter(Boolean);
|
|
1096
1096
|
if (segments.length > 0) {
|
|
1097
1097
|
const lastSegment = segments[segments.length - 1];
|
|
@@ -1298,7 +1298,7 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1298
1298
|
const cleanPrefix = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
1299
1299
|
const cleanMount = mountPath.startsWith("/") ? mountPath : "/" + mountPath;
|
|
1300
1300
|
const nextPrefix = cleanPrefix + cleanMount || "/";
|
|
1301
|
-
collect(child, nextPrefix, group, tag, [...inheritedMiddleware, ...routerMiddleware]);
|
|
1301
|
+
collect(child, nextPrefix, group, tag, [...inheritedMiddleware, ...routerMiddleware], false);
|
|
1302
1302
|
}
|
|
1303
1303
|
};
|
|
1304
1304
|
collect(rootRouter);
|
|
@@ -3550,7 +3550,25 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3550
3550
|
}
|
|
3551
3551
|
return "Ungrouped";
|
|
3552
3552
|
};
|
|
3553
|
-
const
|
|
3553
|
+
const findCommonPrefix = (routes) => {
|
|
3554
|
+
if (routes.length === 0) return [];
|
|
3555
|
+
const allSegments = routes.map((r) => {
|
|
3556
|
+
const cleaned = r.path.replace(/^\/|\/$/g, "");
|
|
3557
|
+
return cleaned.split("/");
|
|
3558
|
+
});
|
|
3559
|
+
const minLength = Math.min(...allSegments.map((s) => s.length));
|
|
3560
|
+
const commonPrefix = [];
|
|
3561
|
+
for (let i = 0; i < minLength; i++) {
|
|
3562
|
+
const segment = allSegments[0][i];
|
|
3563
|
+
if (allSegments.every((segments) => segments[i] === segment)) {
|
|
3564
|
+
commonPrefix.push(segment);
|
|
3565
|
+
} else {
|
|
3566
|
+
break;
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
return commonPrefix;
|
|
3570
|
+
};
|
|
3571
|
+
const createSubgroups = (routes, depth = 0, commonPrefixLength = 0) => {
|
|
3554
3572
|
if (routes.length < 3 || depth > 5) {
|
|
3555
3573
|
return routes.map((route) => ({
|
|
3556
3574
|
name: route.path,
|
|
@@ -3561,7 +3579,8 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3561
3579
|
}
|
|
3562
3580
|
const pathSegments = routes.map((r) => {
|
|
3563
3581
|
const cleaned = r.path.replace(/^\/|\/$/g, "");
|
|
3564
|
-
|
|
3582
|
+
const segments = cleaned.split("/");
|
|
3583
|
+
return segments.slice(commonPrefixLength);
|
|
3565
3584
|
});
|
|
3566
3585
|
const prefixGroups = /* @__PURE__ */ new Map();
|
|
3567
3586
|
const ungrouped = [];
|
|
@@ -3580,13 +3599,30 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3580
3599
|
const result = [];
|
|
3581
3600
|
prefixGroups.forEach((groupRoutes, prefix) => {
|
|
3582
3601
|
if (groupRoutes.length >= 3) {
|
|
3583
|
-
const
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3602
|
+
const nextSegments = /* @__PURE__ */ new Set();
|
|
3603
|
+
groupRoutes.forEach((route, idx) => {
|
|
3604
|
+
const routeIdx = routes.indexOf(route);
|
|
3605
|
+
const segments = pathSegments[routeIdx];
|
|
3606
|
+
if (segments.length > depth + 1) {
|
|
3607
|
+
nextSegments.add(segments[depth + 1]);
|
|
3608
|
+
}
|
|
3609
|
+
});
|
|
3610
|
+
const hasDivergingPaths = nextSegments.size >= 2;
|
|
3611
|
+
const allTerminal = groupRoutes.every((route, idx) => {
|
|
3612
|
+
const routeIdx = routes.indexOf(route);
|
|
3613
|
+
return pathSegments[routeIdx].length === depth + 1;
|
|
3589
3614
|
});
|
|
3615
|
+
if (hasDivergingPaths || allTerminal) {
|
|
3616
|
+
const prefixName = prefix.split("/").pop() || prefix;
|
|
3617
|
+
result.push({
|
|
3618
|
+
name: prefixName,
|
|
3619
|
+
type: "subgroup",
|
|
3620
|
+
path: "/" + prefix,
|
|
3621
|
+
children: createSubgroups(groupRoutes, depth + 1, commonPrefixLength)
|
|
3622
|
+
});
|
|
3623
|
+
} else {
|
|
3624
|
+
result.push(...createSubgroups(groupRoutes, depth + 1, commonPrefixLength));
|
|
3625
|
+
}
|
|
3590
3626
|
} else {
|
|
3591
3627
|
ungrouped.push(...groupRoutes);
|
|
3592
3628
|
}
|
|
@@ -3617,25 +3653,17 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3617
3653
|
addRoute(groupKey, route);
|
|
3618
3654
|
});
|
|
3619
3655
|
});
|
|
3620
|
-
Object.entries(asyncSpec?.channels || {}).forEach(([name, ch]) => {
|
|
3621
|
-
const operations = [];
|
|
3622
|
-
if (ch.publish) operations.push({ method: "recv", op: ch.publish });
|
|
3623
|
-
if (ch.subscribe) operations.push({ method: "send", op: ch.subscribe });
|
|
3624
|
-
operations.forEach(({ method, op }) => {
|
|
3625
|
-
if (!op.operationId) op.operationId = `${method}-${name.replace(/[^a-zA-Z0-9]/g, "-")}`;
|
|
3626
|
-
const route = { method, path: name, op };
|
|
3627
|
-
const source = op["x-shokupan-source"] || op["x-source-info"];
|
|
3628
|
-
const groupKey = getGroupKey(op, source);
|
|
3629
|
-
addRoute(groupKey, route);
|
|
3630
|
-
});
|
|
3631
|
-
});
|
|
3632
3656
|
const hierarchicalGroups = Array.from(hierarchy.entries()).map(([name, routes]) => {
|
|
3633
3657
|
routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
3634
|
-
const
|
|
3658
|
+
const commonPrefix = findCommonPrefix(routes);
|
|
3659
|
+
const commonPrefixPath = "/" + commonPrefix.join("/");
|
|
3660
|
+
const children = createSubgroups(routes, 0, commonPrefix.length);
|
|
3635
3661
|
return {
|
|
3636
3662
|
name,
|
|
3637
3663
|
type: "group",
|
|
3638
|
-
children
|
|
3664
|
+
children,
|
|
3665
|
+
commonPrefixPath
|
|
3666
|
+
// Store for display stripping
|
|
3639
3667
|
};
|
|
3640
3668
|
}).sort((a, b) => {
|
|
3641
3669
|
if (a.name === "Ungrouped") return 1;
|
|
@@ -3674,11 +3702,25 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3674
3702
|
] });
|
|
3675
3703
|
}
|
|
3676
3704
|
function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
3677
|
-
const
|
|
3705
|
+
const stripPrefix = (path, prefix) => {
|
|
3706
|
+
if (!prefix || prefix === "/") return path;
|
|
3707
|
+
if (path.startsWith(prefix)) {
|
|
3708
|
+
const stripped = path.substring(prefix.length);
|
|
3709
|
+
return stripped || "/";
|
|
3710
|
+
}
|
|
3711
|
+
return path;
|
|
3712
|
+
};
|
|
3713
|
+
const formatAndHighlightPath = (path) => {
|
|
3714
|
+
const converted = path.replace(/\{([^}]+)\}/g, ":$1");
|
|
3715
|
+
return converted.replace(/:([a-zA-Z0-9_]+)/g, '<span class="param-highlight">:$1</span>');
|
|
3716
|
+
};
|
|
3717
|
+
const renderNavNode = (node, depth = 0, commonPrefix = "") => {
|
|
3678
3718
|
if (node.type === "route") {
|
|
3679
3719
|
const route = node.routes[0];
|
|
3680
3720
|
const source = route.op["x-shokupan-source"] || route.op["x-source-info"];
|
|
3681
3721
|
const isRuntime = route.op["x-source-info"]?.isRuntime;
|
|
3722
|
+
const displayPath = stripPrefix(route.path, commonPrefix);
|
|
3723
|
+
const highlightedPath = formatAndHighlightPath(displayPath);
|
|
3682
3724
|
return /* @__PURE__ */ jsxs("div", { class: "nav-item-wrapper", style: `padding-left: ${depth * 12}px;`, children: [
|
|
3683
3725
|
/* @__PURE__ */ jsxs(
|
|
3684
3726
|
"a",
|
|
@@ -3689,7 +3731,7 @@ function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
|
3689
3731
|
title: route.path,
|
|
3690
3732
|
children: [
|
|
3691
3733
|
/* @__PURE__ */ jsx("span", { class: `badge badge-${route.method.toUpperCase()}`, children: route.method.toUpperCase() }),
|
|
3692
|
-
/* @__PURE__ */ jsx("span", { class: "nav-label",
|
|
3734
|
+
/* @__PURE__ */ jsx("span", { class: "nav-label", dangerouslySetInnerHTML: { __html: highlightedPath } }),
|
|
3693
3735
|
isRuntime && /* @__PURE__ */ jsx("span", { class: "nav-warning", title: "Static Analysis Failed", children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", children: [
|
|
3694
3736
|
/* @__PURE__ */ jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
|
|
3695
3737
|
/* @__PURE__ */ jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
@@ -3718,7 +3760,7 @@ function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
|
3718
3760
|
/* @__PURE__ */ jsx("span", { class: "chevron", children: /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" }) }) }),
|
|
3719
3761
|
/* @__PURE__ */ jsx("span", { children: node.name })
|
|
3720
3762
|
] }),
|
|
3721
|
-
/* @__PURE__ */ jsx("div", { class: "nav-subgroup-items", children: node.children?.map((child) => renderNavNode(child, depth + 1)) })
|
|
3763
|
+
/* @__PURE__ */ jsx("div", { class: "nav-subgroup-items", children: node.children?.map((child) => renderNavNode(child, depth + 1, commonPrefix)) })
|
|
3722
3764
|
] });
|
|
3723
3765
|
}
|
|
3724
3766
|
};
|
|
@@ -3736,7 +3778,7 @@ function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
|
3736
3778
|
" ",
|
|
3737
3779
|
group.name
|
|
3738
3780
|
] }),
|
|
3739
|
-
/* @__PURE__ */ jsx("div", { class: "nav-items", children: group.children?.map((child) => renderNavNode(child, 0)) })
|
|
3781
|
+
/* @__PURE__ */ jsx("div", { class: "nav-items", children: group.children?.map((child) => renderNavNode(child, 0, group.commonPrefixPath || "")) })
|
|
3740
3782
|
] }, group.name)) })
|
|
3741
3783
|
] });
|
|
3742
3784
|
}
|