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.cjs
CHANGED
|
@@ -1125,7 +1125,7 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1125
1125
|
astRoutes = await getAstRoutes$1(applications);
|
|
1126
1126
|
} catch (e) {
|
|
1127
1127
|
}
|
|
1128
|
-
const collect = (router, prefix = "", currentGroup = defaultTagGroup, defaultTag = defaultTagName, inheritedMiddleware = []) => {
|
|
1128
|
+
const collect = (router, prefix = "", currentGroup = defaultTagGroup, defaultTag = defaultTagName, inheritedMiddleware = [], isRootLevel = true) => {
|
|
1129
1129
|
let group = currentGroup;
|
|
1130
1130
|
let tag = defaultTag;
|
|
1131
1131
|
if (router.config?.group) group = router.config.group;
|
|
@@ -1133,7 +1133,7 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1133
1133
|
tag = router.config.name;
|
|
1134
1134
|
} else {
|
|
1135
1135
|
const mountPath = router[$mountPath];
|
|
1136
|
-
if (mountPath && mountPath !== "/") {
|
|
1136
|
+
if (isRootLevel && mountPath && mountPath !== "/") {
|
|
1137
1137
|
const segments = mountPath.split("/").filter(Boolean);
|
|
1138
1138
|
if (segments.length > 0) {
|
|
1139
1139
|
const lastSegment = segments[segments.length - 1];
|
|
@@ -1340,7 +1340,7 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1340
1340
|
const cleanPrefix = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
1341
1341
|
const cleanMount = mountPath.startsWith("/") ? mountPath : "/" + mountPath;
|
|
1342
1342
|
const nextPrefix = cleanPrefix + cleanMount || "/";
|
|
1343
|
-
collect(child, nextPrefix, group, tag, [...inheritedMiddleware, ...routerMiddleware]);
|
|
1343
|
+
collect(child, nextPrefix, group, tag, [...inheritedMiddleware, ...routerMiddleware], false);
|
|
1344
1344
|
}
|
|
1345
1345
|
};
|
|
1346
1346
|
collect(rootRouter);
|
|
@@ -3592,7 +3592,25 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3592
3592
|
}
|
|
3593
3593
|
return "Ungrouped";
|
|
3594
3594
|
};
|
|
3595
|
-
const
|
|
3595
|
+
const findCommonPrefix = (routes) => {
|
|
3596
|
+
if (routes.length === 0) return [];
|
|
3597
|
+
const allSegments = routes.map((r) => {
|
|
3598
|
+
const cleaned = r.path.replace(/^\/|\/$/g, "");
|
|
3599
|
+
return cleaned.split("/");
|
|
3600
|
+
});
|
|
3601
|
+
const minLength = Math.min(...allSegments.map((s) => s.length));
|
|
3602
|
+
const commonPrefix = [];
|
|
3603
|
+
for (let i = 0; i < minLength; i++) {
|
|
3604
|
+
const segment = allSegments[0][i];
|
|
3605
|
+
if (allSegments.every((segments) => segments[i] === segment)) {
|
|
3606
|
+
commonPrefix.push(segment);
|
|
3607
|
+
} else {
|
|
3608
|
+
break;
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
return commonPrefix;
|
|
3612
|
+
};
|
|
3613
|
+
const createSubgroups = (routes, depth = 0, commonPrefixLength = 0) => {
|
|
3596
3614
|
if (routes.length < 3 || depth > 5) {
|
|
3597
3615
|
return routes.map((route) => ({
|
|
3598
3616
|
name: route.path,
|
|
@@ -3603,7 +3621,8 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3603
3621
|
}
|
|
3604
3622
|
const pathSegments = routes.map((r) => {
|
|
3605
3623
|
const cleaned = r.path.replace(/^\/|\/$/g, "");
|
|
3606
|
-
|
|
3624
|
+
const segments = cleaned.split("/");
|
|
3625
|
+
return segments.slice(commonPrefixLength);
|
|
3607
3626
|
});
|
|
3608
3627
|
const prefixGroups = /* @__PURE__ */ new Map();
|
|
3609
3628
|
const ungrouped = [];
|
|
@@ -3622,13 +3641,30 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3622
3641
|
const result = [];
|
|
3623
3642
|
prefixGroups.forEach((groupRoutes, prefix) => {
|
|
3624
3643
|
if (groupRoutes.length >= 3) {
|
|
3625
|
-
const
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3644
|
+
const nextSegments = /* @__PURE__ */ new Set();
|
|
3645
|
+
groupRoutes.forEach((route, idx) => {
|
|
3646
|
+
const routeIdx = routes.indexOf(route);
|
|
3647
|
+
const segments = pathSegments[routeIdx];
|
|
3648
|
+
if (segments.length > depth + 1) {
|
|
3649
|
+
nextSegments.add(segments[depth + 1]);
|
|
3650
|
+
}
|
|
3651
|
+
});
|
|
3652
|
+
const hasDivergingPaths = nextSegments.size >= 2;
|
|
3653
|
+
const allTerminal = groupRoutes.every((route, idx) => {
|
|
3654
|
+
const routeIdx = routes.indexOf(route);
|
|
3655
|
+
return pathSegments[routeIdx].length === depth + 1;
|
|
3631
3656
|
});
|
|
3657
|
+
if (hasDivergingPaths || allTerminal) {
|
|
3658
|
+
const prefixName = prefix.split("/").pop() || prefix;
|
|
3659
|
+
result.push({
|
|
3660
|
+
name: prefixName,
|
|
3661
|
+
type: "subgroup",
|
|
3662
|
+
path: "/" + prefix,
|
|
3663
|
+
children: createSubgroups(groupRoutes, depth + 1, commonPrefixLength)
|
|
3664
|
+
});
|
|
3665
|
+
} else {
|
|
3666
|
+
result.push(...createSubgroups(groupRoutes, depth + 1, commonPrefixLength));
|
|
3667
|
+
}
|
|
3632
3668
|
} else {
|
|
3633
3669
|
ungrouped.push(...groupRoutes);
|
|
3634
3670
|
}
|
|
@@ -3659,25 +3695,17 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3659
3695
|
addRoute(groupKey, route);
|
|
3660
3696
|
});
|
|
3661
3697
|
});
|
|
3662
|
-
Object.entries(asyncSpec?.channels || {}).forEach(([name, ch]) => {
|
|
3663
|
-
const operations = [];
|
|
3664
|
-
if (ch.publish) operations.push({ method: "recv", op: ch.publish });
|
|
3665
|
-
if (ch.subscribe) operations.push({ method: "send", op: ch.subscribe });
|
|
3666
|
-
operations.forEach(({ method, op }) => {
|
|
3667
|
-
if (!op.operationId) op.operationId = `${method}-${name.replace(/[^a-zA-Z0-9]/g, "-")}`;
|
|
3668
|
-
const route = { method, path: name, op };
|
|
3669
|
-
const source = op["x-shokupan-source"] || op["x-source-info"];
|
|
3670
|
-
const groupKey = getGroupKey(op, source);
|
|
3671
|
-
addRoute(groupKey, route);
|
|
3672
|
-
});
|
|
3673
|
-
});
|
|
3674
3698
|
const hierarchicalGroups = Array.from(hierarchy.entries()).map(([name, routes]) => {
|
|
3675
3699
|
routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
3676
|
-
const
|
|
3700
|
+
const commonPrefix = findCommonPrefix(routes);
|
|
3701
|
+
const commonPrefixPath = "/" + commonPrefix.join("/");
|
|
3702
|
+
const children = createSubgroups(routes, 0, commonPrefix.length);
|
|
3677
3703
|
return {
|
|
3678
3704
|
name,
|
|
3679
3705
|
type: "group",
|
|
3680
|
-
children
|
|
3706
|
+
children,
|
|
3707
|
+
commonPrefixPath
|
|
3708
|
+
// Store for display stripping
|
|
3681
3709
|
};
|
|
3682
3710
|
}).sort((a, b) => {
|
|
3683
3711
|
if (a.name === "Ungrouped") return 1;
|
|
@@ -3716,11 +3744,25 @@ function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
|
3716
3744
|
] });
|
|
3717
3745
|
}
|
|
3718
3746
|
function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
3719
|
-
const
|
|
3747
|
+
const stripPrefix = (path2, prefix) => {
|
|
3748
|
+
if (!prefix || prefix === "/") return path2;
|
|
3749
|
+
if (path2.startsWith(prefix)) {
|
|
3750
|
+
const stripped = path2.substring(prefix.length);
|
|
3751
|
+
return stripped || "/";
|
|
3752
|
+
}
|
|
3753
|
+
return path2;
|
|
3754
|
+
};
|
|
3755
|
+
const formatAndHighlightPath = (path2) => {
|
|
3756
|
+
const converted = path2.replace(/\{([^}]+)\}/g, ":$1");
|
|
3757
|
+
return converted.replace(/:([a-zA-Z0-9_]+)/g, '<span class="param-highlight">:$1</span>');
|
|
3758
|
+
};
|
|
3759
|
+
const renderNavNode = (node, depth = 0, commonPrefix = "") => {
|
|
3720
3760
|
if (node.type === "route") {
|
|
3721
3761
|
const route = node.routes[0];
|
|
3722
3762
|
const source = route.op["x-shokupan-source"] || route.op["x-source-info"];
|
|
3723
3763
|
const isRuntime = route.op["x-source-info"]?.isRuntime;
|
|
3764
|
+
const displayPath = stripPrefix(route.path, commonPrefix);
|
|
3765
|
+
const highlightedPath = formatAndHighlightPath(displayPath);
|
|
3724
3766
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { class: "nav-item-wrapper", style: `padding-left: ${depth * 12}px;`, children: [
|
|
3725
3767
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3726
3768
|
"a",
|
|
@@ -3731,7 +3773,7 @@ function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
|
3731
3773
|
title: route.path,
|
|
3732
3774
|
children: [
|
|
3733
3775
|
/* @__PURE__ */ jsxRuntime.jsx("span", { class: `badge badge-${route.method.toUpperCase()}`, children: route.method.toUpperCase() }),
|
|
3734
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { class: "nav-label",
|
|
3776
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { class: "nav-label", dangerouslySetInnerHTML: { __html: highlightedPath } }),
|
|
3735
3777
|
isRuntime && /* @__PURE__ */ jsxRuntime.jsx("span", { class: "nav-warning", title: "Static Analysis Failed", children: /* @__PURE__ */ jsxRuntime.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: [
|
|
3736
3778
|
/* @__PURE__ */ jsxRuntime.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" }),
|
|
3737
3779
|
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
@@ -3760,7 +3802,7 @@ function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
|
3760
3802
|
/* @__PURE__ */ jsxRuntime.jsx("span", { class: "chevron", children: /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" }) }) }),
|
|
3761
3803
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: node.name })
|
|
3762
3804
|
] }),
|
|
3763
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "nav-subgroup-items", children: node.children?.map((child) => renderNavNode(child, depth + 1)) })
|
|
3805
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "nav-subgroup-items", children: node.children?.map((child) => renderNavNode(child, depth + 1, commonPrefix)) })
|
|
3764
3806
|
] });
|
|
3765
3807
|
}
|
|
3766
3808
|
};
|
|
@@ -3778,7 +3820,7 @@ function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
|
3778
3820
|
" ",
|
|
3779
3821
|
group.name
|
|
3780
3822
|
] }),
|
|
3781
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "nav-items", children: group.children?.map((child) => renderNavNode(child, 0)) })
|
|
3823
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "nav-items", children: group.children?.map((child) => renderNavNode(child, 0, group.commonPrefixPath || "")) })
|
|
3782
3824
|
] }, group.name)) })
|
|
3783
3825
|
] });
|
|
3784
3826
|
}
|