shokupan 0.10.0 → 0.10.2
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 +320 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +320 -39
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -25,18 +25,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
25
25
|
const nanoid = require("nanoid");
|
|
26
26
|
const promises = require("node:fs/promises");
|
|
27
27
|
const node_util = require("node:util");
|
|
28
|
-
const api = require("@opentelemetry/api");
|
|
29
|
-
const jsYaml = require("js-yaml");
|
|
30
|
-
const node_async_hooks = require("node:async_hooks");
|
|
31
28
|
const surrealdb = require("surrealdb");
|
|
32
29
|
const eta$1 = require("eta");
|
|
33
30
|
const promises$1 = require("fs/promises");
|
|
34
31
|
const path = require("path");
|
|
32
|
+
const api = require("@opentelemetry/api");
|
|
33
|
+
const jsYaml = require("js-yaml");
|
|
34
|
+
const node_async_hooks = require("node:async_hooks");
|
|
35
35
|
const os = require("node:os");
|
|
36
|
-
const path$1 = require("node:path");
|
|
37
|
-
const node_url = require("node:url");
|
|
38
36
|
const renderToString = require("preact-render-to-string");
|
|
39
37
|
const jsxRuntime = require("preact/jsx-runtime");
|
|
38
|
+
const path$1 = require("node:path");
|
|
39
|
+
const node_url = require("node:url");
|
|
40
40
|
const cluster = require("node:cluster");
|
|
41
41
|
const net = require("node:net");
|
|
42
42
|
const node_perf_hooks = require("node:perf_hooks");
|
|
@@ -1359,40 +1359,6 @@ async function generateOpenApi(rootRouter, options = {}) {
|
|
|
1359
1359
|
"x-tagGroups": xTagGroups
|
|
1360
1360
|
};
|
|
1361
1361
|
}
|
|
1362
|
-
class RequestContextStore {
|
|
1363
|
-
request;
|
|
1364
|
-
span;
|
|
1365
|
-
}
|
|
1366
|
-
const asyncContext = new node_async_hooks.AsyncLocalStorage();
|
|
1367
|
-
class HttpError extends Error {
|
|
1368
|
-
status;
|
|
1369
|
-
constructor(message, status) {
|
|
1370
|
-
super(message);
|
|
1371
|
-
this.name = "HttpError";
|
|
1372
|
-
this.status = status;
|
|
1373
|
-
if (Error.captureStackTrace) {
|
|
1374
|
-
Error.captureStackTrace(this, HttpError);
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
function getErrorStatus(err) {
|
|
1379
|
-
if (!err || typeof err !== "object") {
|
|
1380
|
-
return 500;
|
|
1381
|
-
}
|
|
1382
|
-
if (typeof err.status === "number") {
|
|
1383
|
-
return err.status;
|
|
1384
|
-
}
|
|
1385
|
-
if (typeof err.statusCode === "number") {
|
|
1386
|
-
return err.statusCode;
|
|
1387
|
-
}
|
|
1388
|
-
return 500;
|
|
1389
|
-
}
|
|
1390
|
-
class EventError extends HttpError {
|
|
1391
|
-
constructor(message = "Event Error") {
|
|
1392
|
-
super(message, 500);
|
|
1393
|
-
this.name = "EventError";
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
1362
|
const eta = new eta$1.Eta();
|
|
1397
1363
|
function serveStatic(config, prefix) {
|
|
1398
1364
|
const rootPath = path.resolve(config.root || ".");
|
|
@@ -1578,6 +1544,35 @@ function Inject(token) {
|
|
|
1578
1544
|
});
|
|
1579
1545
|
};
|
|
1580
1546
|
}
|
|
1547
|
+
class HttpError extends Error {
|
|
1548
|
+
status;
|
|
1549
|
+
constructor(message, status) {
|
|
1550
|
+
super(message);
|
|
1551
|
+
this.name = "HttpError";
|
|
1552
|
+
this.status = status;
|
|
1553
|
+
if (Error.captureStackTrace) {
|
|
1554
|
+
Error.captureStackTrace(this, HttpError);
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
function getErrorStatus(err) {
|
|
1559
|
+
if (!err || typeof err !== "object") {
|
|
1560
|
+
return 500;
|
|
1561
|
+
}
|
|
1562
|
+
if (typeof err.status === "number") {
|
|
1563
|
+
return err.status;
|
|
1564
|
+
}
|
|
1565
|
+
if (typeof err.statusCode === "number") {
|
|
1566
|
+
return err.statusCode;
|
|
1567
|
+
}
|
|
1568
|
+
return 500;
|
|
1569
|
+
}
|
|
1570
|
+
class EventError extends HttpError {
|
|
1571
|
+
constructor(message = "Event Error") {
|
|
1572
|
+
super(message, 500);
|
|
1573
|
+
this.name = "EventError";
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1581
1576
|
const tracer = api.trace.getTracer("shokupan.middleware");
|
|
1582
1577
|
function traceHandler(fn, name) {
|
|
1583
1578
|
return async function(...args) {
|
|
@@ -1767,6 +1762,8 @@ var RouteParamType = /* @__PURE__ */ ((RouteParamType2) => {
|
|
|
1767
1762
|
RouteParamType2["CONTEXT"] = "CONTEXT";
|
|
1768
1763
|
return RouteParamType2;
|
|
1769
1764
|
})(RouteParamType || {});
|
|
1765
|
+
const RouterRegistry = /* @__PURE__ */ new Map();
|
|
1766
|
+
const ShokupanApplicationTree = {};
|
|
1770
1767
|
class ShokupanRouter {
|
|
1771
1768
|
constructor(config) {
|
|
1772
1769
|
this.config = config;
|
|
@@ -2761,6 +2758,11 @@ class ShokupanRouter {
|
|
|
2761
2758
|
}
|
|
2762
2759
|
}
|
|
2763
2760
|
}
|
|
2761
|
+
class RequestContextStore {
|
|
2762
|
+
request;
|
|
2763
|
+
span;
|
|
2764
|
+
}
|
|
2765
|
+
const asyncContext = new node_async_hooks.AsyncLocalStorage();
|
|
2764
2766
|
class SystemCpuMonitor {
|
|
2765
2767
|
constructor(intervalMs = 1e3) {
|
|
2766
2768
|
this.intervalMs = intervalMs;
|
|
@@ -3565,6 +3567,281 @@ function Event(eventName) {
|
|
|
3565
3567
|
function RateLimit(options) {
|
|
3566
3568
|
return Use(RateLimitMiddleware(options));
|
|
3567
3569
|
}
|
|
3570
|
+
function ApiExplorerApp({ spec, asyncSpec, config }) {
|
|
3571
|
+
const hierarchy = /* @__PURE__ */ new Map();
|
|
3572
|
+
const addRoute = (groupKey, route) => {
|
|
3573
|
+
if (!hierarchy.has(groupKey)) {
|
|
3574
|
+
hierarchy.set(groupKey, []);
|
|
3575
|
+
}
|
|
3576
|
+
hierarchy.get(groupKey).push(route);
|
|
3577
|
+
};
|
|
3578
|
+
const getGroupKey = (op, source) => {
|
|
3579
|
+
if (op.tags && op.tags.length > 0) {
|
|
3580
|
+
const tag = typeof op.tags[0] === "string" ? op.tags[0] : op.tags[0].name;
|
|
3581
|
+
if (!tag.startsWith("/")) return tag;
|
|
3582
|
+
}
|
|
3583
|
+
if (source?.className) return source.className;
|
|
3584
|
+
if (source?.file) {
|
|
3585
|
+
const parts = source.file.split("/");
|
|
3586
|
+
const filename = parts[parts.length - 1].replace(/\.(ts|js)$/, "");
|
|
3587
|
+
return filename.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3588
|
+
}
|
|
3589
|
+
if (op.tags && op.tags.length > 0) {
|
|
3590
|
+
const tag = typeof op.tags[0] === "string" ? op.tags[0] : op.tags[0].name;
|
|
3591
|
+
return tag;
|
|
3592
|
+
}
|
|
3593
|
+
return "Ungrouped";
|
|
3594
|
+
};
|
|
3595
|
+
const createSubgroups = (routes, depth = 0) => {
|
|
3596
|
+
if (routes.length < 3 || depth > 5) {
|
|
3597
|
+
return routes.map((route) => ({
|
|
3598
|
+
name: route.path,
|
|
3599
|
+
type: "route",
|
|
3600
|
+
path: route.path,
|
|
3601
|
+
routes: [route]
|
|
3602
|
+
}));
|
|
3603
|
+
}
|
|
3604
|
+
const pathSegments = routes.map((r) => {
|
|
3605
|
+
const cleaned = r.path.replace(/^\/|\/$/g, "");
|
|
3606
|
+
return cleaned.split("/");
|
|
3607
|
+
});
|
|
3608
|
+
const prefixGroups = /* @__PURE__ */ new Map();
|
|
3609
|
+
const ungrouped = [];
|
|
3610
|
+
routes.forEach((route, idx) => {
|
|
3611
|
+
const segments = pathSegments[idx];
|
|
3612
|
+
if (segments.length <= depth) {
|
|
3613
|
+
ungrouped.push(route);
|
|
3614
|
+
return;
|
|
3615
|
+
}
|
|
3616
|
+
const prefix = segments.slice(0, depth + 1).join("/");
|
|
3617
|
+
if (!prefixGroups.has(prefix)) {
|
|
3618
|
+
prefixGroups.set(prefix, []);
|
|
3619
|
+
}
|
|
3620
|
+
prefixGroups.get(prefix).push(route);
|
|
3621
|
+
});
|
|
3622
|
+
const result = [];
|
|
3623
|
+
prefixGroups.forEach((groupRoutes, prefix) => {
|
|
3624
|
+
if (groupRoutes.length >= 3) {
|
|
3625
|
+
const prefixName = prefix.split("/").pop() || prefix;
|
|
3626
|
+
result.push({
|
|
3627
|
+
name: prefixName,
|
|
3628
|
+
type: "subgroup",
|
|
3629
|
+
path: "/" + prefix,
|
|
3630
|
+
children: createSubgroups(groupRoutes, depth + 1)
|
|
3631
|
+
});
|
|
3632
|
+
} else {
|
|
3633
|
+
ungrouped.push(...groupRoutes);
|
|
3634
|
+
}
|
|
3635
|
+
});
|
|
3636
|
+
ungrouped.forEach((route) => {
|
|
3637
|
+
result.push({
|
|
3638
|
+
name: route.path,
|
|
3639
|
+
type: "route",
|
|
3640
|
+
path: route.path,
|
|
3641
|
+
routes: [route]
|
|
3642
|
+
});
|
|
3643
|
+
});
|
|
3644
|
+
result.sort((a, b) => {
|
|
3645
|
+
if (a.type === "subgroup" && b.type !== "subgroup") return -1;
|
|
3646
|
+
if (a.type !== "subgroup" && b.type === "subgroup") return 1;
|
|
3647
|
+
return a.name.localeCompare(b.name);
|
|
3648
|
+
});
|
|
3649
|
+
return result;
|
|
3650
|
+
};
|
|
3651
|
+
Object.entries(spec.paths || {}).forEach(([path2, methods]) => {
|
|
3652
|
+
Object.entries(methods).forEach(([method, op]) => {
|
|
3653
|
+
if (!op.operationId) {
|
|
3654
|
+
op.operationId = `${method}-${path2.replace(/\//g, "-").replace(/[{}:]/g, "")}`;
|
|
3655
|
+
}
|
|
3656
|
+
const route = { method, path: path2, op };
|
|
3657
|
+
const source = op["x-shokupan-source"];
|
|
3658
|
+
const groupKey = getGroupKey(op, source);
|
|
3659
|
+
addRoute(groupKey, route);
|
|
3660
|
+
});
|
|
3661
|
+
});
|
|
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
|
+
const hierarchicalGroups = Array.from(hierarchy.entries()).map(([name, routes]) => {
|
|
3675
|
+
routes.sort((a, b) => a.path.localeCompare(b.path));
|
|
3676
|
+
const children = createSubgroups(routes);
|
|
3677
|
+
return {
|
|
3678
|
+
name,
|
|
3679
|
+
type: "group",
|
|
3680
|
+
children
|
|
3681
|
+
};
|
|
3682
|
+
}).sort((a, b) => {
|
|
3683
|
+
if (a.name === "Ungrouped") return 1;
|
|
3684
|
+
if (b.name === "Ungrouped") return -1;
|
|
3685
|
+
return a.name.localeCompare(b.name);
|
|
3686
|
+
});
|
|
3687
|
+
const allRoutes = Array.from(hierarchy.values()).flat();
|
|
3688
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("html", { lang: "en", children: [
|
|
3689
|
+
/* @__PURE__ */ jsxRuntime.jsxs("head", { children: [
|
|
3690
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { charSet: "UTF-8" }),
|
|
3691
|
+
/* @__PURE__ */ jsxRuntime.jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }),
|
|
3692
|
+
/* @__PURE__ */ jsxRuntime.jsx("title", { children: spec.info?.title || "API Explorer" }),
|
|
3693
|
+
/* @__PURE__ */ jsxRuntime.jsx("link", { rel: "stylesheet", href: "style.css" }),
|
|
3694
|
+
/* @__PURE__ */ jsxRuntime.jsx("link", { rel: "stylesheet", href: "theme.css" }),
|
|
3695
|
+
/* @__PURE__ */ jsxRuntime.jsx("script", { src: "https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js" }),
|
|
3696
|
+
/* @__PURE__ */ jsxRuntime.jsx("script", { src: "https://cdn.jsdelivr.net/npm/monaco-editor@0.45.0/min/vs/loader.js" }),
|
|
3697
|
+
/* @__PURE__ */ jsxRuntime.jsx("script", { dangerouslySetInnerHTML: {
|
|
3698
|
+
__html: `
|
|
3699
|
+
(function() {
|
|
3700
|
+
if (!window.location.pathname.endsWith('/') && !window.location.pathname.split('/').pop().includes('.')) {
|
|
3701
|
+
var newUrl = window.location.pathname + '/' + window.location.search + window.location.hash;
|
|
3702
|
+
window.history.replaceState(null, null, newUrl);
|
|
3703
|
+
window.location.reload();
|
|
3704
|
+
}
|
|
3705
|
+
})();
|
|
3706
|
+
`
|
|
3707
|
+
} })
|
|
3708
|
+
] }),
|
|
3709
|
+
/* @__PURE__ */ jsxRuntime.jsxs("body", { class: "dark-theme", children: [
|
|
3710
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { id: "app", children: [
|
|
3711
|
+
/* @__PURE__ */ jsxRuntime.jsx(Sidebar$1, { spec, hierarchicalGroups }),
|
|
3712
|
+
/* @__PURE__ */ jsxRuntime.jsx(MainContent$1, { allRoutes, config, spec })
|
|
3713
|
+
] }),
|
|
3714
|
+
/* @__PURE__ */ jsxRuntime.jsx("script", { src: "explorer-client.mjs", type: "module" })
|
|
3715
|
+
] })
|
|
3716
|
+
] });
|
|
3717
|
+
}
|
|
3718
|
+
function Sidebar$1({ spec, hierarchicalGroups }) {
|
|
3719
|
+
const renderNavNode = (node, depth = 0) => {
|
|
3720
|
+
if (node.type === "route") {
|
|
3721
|
+
const route = node.routes[0];
|
|
3722
|
+
const source = route.op["x-shokupan-source"] || route.op["x-source-info"];
|
|
3723
|
+
const isRuntime = route.op["x-source-info"]?.isRuntime;
|
|
3724
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { class: "nav-item-wrapper", style: `padding-left: ${depth * 12}px;`, children: [
|
|
3725
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3726
|
+
"a",
|
|
3727
|
+
{
|
|
3728
|
+
href: `#${route.op.operationId}`,
|
|
3729
|
+
class: "nav-item",
|
|
3730
|
+
"data-id": route.op.operationId,
|
|
3731
|
+
title: route.path,
|
|
3732
|
+
children: [
|
|
3733
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { class: `badge badge-${route.method.toUpperCase()}`, children: route.method.toUpperCase() }),
|
|
3734
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { class: "nav-label", children: node.name }),
|
|
3735
|
+
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
|
+
/* @__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
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
|
|
3738
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
|
|
3739
|
+
] }) })
|
|
3740
|
+
]
|
|
3741
|
+
},
|
|
3742
|
+
route.op.operationId
|
|
3743
|
+
),
|
|
3744
|
+
source?.file && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3745
|
+
"a",
|
|
3746
|
+
{
|
|
3747
|
+
href: `vscode://file/${source.file}:${source.line || 1}`,
|
|
3748
|
+
class: "nav-source-link",
|
|
3749
|
+
title: `${source.file}:${source.line || 1}`,
|
|
3750
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
|
|
3751
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16 18 22 12 16 6" }),
|
|
3752
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "8 6 2 12 8 18" })
|
|
3753
|
+
] })
|
|
3754
|
+
}
|
|
3755
|
+
)
|
|
3756
|
+
] });
|
|
3757
|
+
} else if (node.type === "subgroup") {
|
|
3758
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { class: "nav-subgroup collapsed", style: `padding-left: ${depth * 12}px;`, children: [
|
|
3759
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { class: "nav-subgroup-title", children: [
|
|
3760
|
+
/* @__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
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: node.name })
|
|
3762
|
+
] }),
|
|
3763
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "nav-subgroup-items", children: node.children?.map((child) => renderNavNode(child, depth + 1)) })
|
|
3764
|
+
] });
|
|
3765
|
+
}
|
|
3766
|
+
};
|
|
3767
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("aside", { class: "sidebar", children: [
|
|
3768
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "resize-handle" }),
|
|
3769
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { class: "sidebar-header", children: [
|
|
3770
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { class: "toggle-sidebar", children: "☰" }),
|
|
3771
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { children: spec.info?.title }),
|
|
3772
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "version", children: spec.info?.version })
|
|
3773
|
+
] }),
|
|
3774
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "sidebar-collapse-trigger", children: "➔" }),
|
|
3775
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { class: "nav-groups", children: hierarchicalGroups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { class: "nav-group collapsed", children: [
|
|
3776
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { class: "nav-group-title", children: [
|
|
3777
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { class: "chevron", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", 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" }) }) }),
|
|
3778
|
+
" ",
|
|
3779
|
+
group.name
|
|
3780
|
+
] }),
|
|
3781
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { class: "nav-items", children: group.children?.map((child) => renderNavNode(child, 0)) })
|
|
3782
|
+
] }, group.name)) })
|
|
3783
|
+
] });
|
|
3784
|
+
}
|
|
3785
|
+
function MainContent$1({ allRoutes, config, spec }) {
|
|
3786
|
+
const explorerData = JSON.stringify({
|
|
3787
|
+
routes: allRoutes,
|
|
3788
|
+
config,
|
|
3789
|
+
info: spec.info
|
|
3790
|
+
});
|
|
3791
|
+
const safeJson = explorerData.replace(/<\/script>/g, "<\\/script>");
|
|
3792
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("main", { class: "content", id: "main-content", children: [
|
|
3793
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { id: "ide-container", children: /* @__PURE__ */ jsxRuntime.jsx("div", { class: "empty-state", children: "Select a request to view details" }) }),
|
|
3794
|
+
/* @__PURE__ */ jsxRuntime.jsx("script", { id: "explorer-data", type: "application/json", dangerouslySetInnerHTML: { __html: safeJson } })
|
|
3795
|
+
] });
|
|
3796
|
+
}
|
|
3797
|
+
class ApiExplorerPlugin extends ShokupanRouter {
|
|
3798
|
+
constructor(pluginOptions) {
|
|
3799
|
+
super({ renderer: renderToString });
|
|
3800
|
+
this.pluginOptions = pluginOptions;
|
|
3801
|
+
pluginOptions.path ??= "/explorer";
|
|
3802
|
+
const serveFile = async (ctx, file, type) => {
|
|
3803
|
+
const content = await promises$1.readFile(path.join(__dirname, "static", file), "utf-8");
|
|
3804
|
+
ctx.set("Content-Type", type);
|
|
3805
|
+
return ctx.send(content);
|
|
3806
|
+
};
|
|
3807
|
+
const stripSourceCode = (spec) => {
|
|
3808
|
+
if (!spec || !spec.paths) return spec;
|
|
3809
|
+
Object.values(spec.paths).forEach((methods) => {
|
|
3810
|
+
Object.values(methods).forEach((op) => {
|
|
3811
|
+
if (op["x-source-info"]?.snippet) {
|
|
3812
|
+
delete op["x-source-info"].snippet;
|
|
3813
|
+
}
|
|
3814
|
+
if (op["x-shokupan-source"]?.code) {
|
|
3815
|
+
delete op["x-shokupan-source"].code;
|
|
3816
|
+
}
|
|
3817
|
+
});
|
|
3818
|
+
});
|
|
3819
|
+
return spec;
|
|
3820
|
+
};
|
|
3821
|
+
this.get("/style.css", (ctx) => serveFile(ctx, "style.css", "text/css"));
|
|
3822
|
+
this.get("/theme.css", (ctx) => serveFile(ctx, "theme.css", "text/css"));
|
|
3823
|
+
this.get("/explorer-client.mjs", (ctx) => serveFile(ctx, "explorer-client.mjs", "application/javascript"));
|
|
3824
|
+
this.get("/_source", async (ctx) => {
|
|
3825
|
+
const file = ctx.query["file"];
|
|
3826
|
+
if (!file) return ctx.text("Missing file parameter", 400);
|
|
3827
|
+
try {
|
|
3828
|
+
const content = await promises$1.readFile(file, "utf-8");
|
|
3829
|
+
return ctx.text(content);
|
|
3830
|
+
} catch (err) {
|
|
3831
|
+
return ctx.text("File not found", 404);
|
|
3832
|
+
}
|
|
3833
|
+
});
|
|
3834
|
+
this.get("/openapi.json", async (ctx) => {
|
|
3835
|
+
const spec = this.root.openApiSpec ? structuredClone(this.root.openApiSpec) : await (this.root || this).generateApiSpec();
|
|
3836
|
+
return ctx.json(stripSourceCode(spec));
|
|
3837
|
+
});
|
|
3838
|
+
this.get("/", async (ctx) => {
|
|
3839
|
+
const spec = this.root.openApiSpec ? structuredClone(this.root.openApiSpec) : await (this.root || this).generateApiSpec();
|
|
3840
|
+
const asyncSpec = ctx.app.asyncApiSpec;
|
|
3841
|
+
return ctx.jsx(ApiExplorerApp({ spec: stripSourceCode(spec), asyncSpec }));
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3568
3845
|
function AsyncApiApp({ spec, serverUrl, base, disableSourceView, navTree }) {
|
|
3569
3846
|
return /* @__PURE__ */ jsxRuntime.jsxs("html", { lang: "en", children: [
|
|
3570
3847
|
/* @__PURE__ */ jsxRuntime.jsxs("head", { children: [
|
|
@@ -6405,6 +6682,7 @@ exports.$socket = $socket;
|
|
|
6405
6682
|
exports.$url = $url;
|
|
6406
6683
|
exports.$ws = $ws;
|
|
6407
6684
|
exports.All = All;
|
|
6685
|
+
exports.ApiExplorerPlugin = ApiExplorerPlugin;
|
|
6408
6686
|
exports.AsyncApiPlugin = AsyncApiPlugin;
|
|
6409
6687
|
exports.AuthPlugin = AuthPlugin;
|
|
6410
6688
|
exports.Body = Body;
|
|
@@ -6435,13 +6713,16 @@ exports.RateLimit = RateLimit;
|
|
|
6435
6713
|
exports.RateLimitMiddleware = RateLimitMiddleware;
|
|
6436
6714
|
exports.Req = Req;
|
|
6437
6715
|
exports.RouteParamType = RouteParamType;
|
|
6716
|
+
exports.RouterRegistry = RouterRegistry;
|
|
6438
6717
|
exports.ScalarPlugin = ScalarPlugin;
|
|
6439
6718
|
exports.SecurityHeaders = SecurityHeaders;
|
|
6440
6719
|
exports.Session = Session;
|
|
6441
6720
|
exports.Shokupan = Shokupan;
|
|
6721
|
+
exports.ShokupanApplicationTree = ShokupanApplicationTree;
|
|
6442
6722
|
exports.ShokupanContext = ShokupanContext;
|
|
6443
6723
|
exports.ShokupanRequest = ShokupanRequest;
|
|
6444
6724
|
exports.ShokupanResponse = ShokupanResponse;
|
|
6725
|
+
exports.ShokupanRouter = ShokupanRouter;
|
|
6445
6726
|
exports.Spec = Spec;
|
|
6446
6727
|
exports.Use = Use;
|
|
6447
6728
|
exports.ValidationError = ValidationError;
|