shokupan 0.10.4 → 0.11.0
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/{analyzer-CKLGLFtx.cjs → analyzer-BAhvpNY_.cjs} +2 -7
- package/dist/{analyzer-CKLGLFtx.cjs.map → analyzer-BAhvpNY_.cjs.map} +1 -1
- package/dist/{analyzer-BqIe1p0R.js → analyzer-CnKnQ5KV.js} +3 -8
- package/dist/{analyzer-BqIe1p0R.js.map → analyzer-CnKnQ5KV.js.map} +1 -1
- package/dist/{analyzer.impl-D9Yi1Hax.cjs → analyzer.impl-CfpMu4-g.cjs} +586 -40
- package/dist/analyzer.impl-CfpMu4-g.cjs.map +1 -0
- package/dist/{analyzer.impl-CV6W1Eq7.js → analyzer.impl-DCiqlXI5.js} +586 -40
- package/dist/analyzer.impl-DCiqlXI5.js.map +1 -0
- package/dist/cli.cjs +206 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +206 -18
- package/dist/cli.js.map +1 -1
- package/dist/context.d.ts +6 -1
- package/dist/index.cjs +2405 -1008
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2402 -1006
- package/dist/index.js.map +1 -1
- package/dist/plugins/application/api-explorer/static/explorer-client.mjs +423 -30
- package/dist/plugins/application/api-explorer/static/style.css +351 -10
- package/dist/plugins/application/api-explorer/static/theme.css +7 -2
- package/dist/plugins/application/asyncapi/generator.d.ts +4 -0
- package/dist/plugins/application/asyncapi/static/asyncapi-client.mjs +154 -22
- package/dist/plugins/application/asyncapi/static/style.css +24 -8
- package/dist/plugins/application/dashboard/fetch-interceptor.d.ts +107 -0
- package/dist/plugins/application/dashboard/metrics-collector.d.ts +38 -2
- package/dist/plugins/application/dashboard/plugin.d.ts +44 -1
- package/dist/plugins/application/dashboard/static/charts.js +127 -62
- package/dist/plugins/application/dashboard/static/client.js +160 -0
- package/dist/plugins/application/dashboard/static/graph.mjs +167 -56
- package/dist/plugins/application/dashboard/static/reactflow.css +20 -10
- package/dist/plugins/application/dashboard/static/registry.js +112 -8
- package/dist/plugins/application/dashboard/static/requests.js +868 -58
- package/dist/plugins/application/dashboard/static/styles.css +186 -14
- package/dist/plugins/application/dashboard/static/tabs.js +44 -9
- package/dist/plugins/application/dashboard/static/theme.css +7 -2
- package/dist/plugins/application/openapi/analyzer.impl.d.ts +61 -1
- package/dist/plugins/application/openapi/openapi.d.ts +3 -0
- package/dist/plugins/application/shared/ast-utils.d.ts +7 -0
- package/dist/router.d.ts +55 -16
- package/dist/shokupan.d.ts +7 -2
- package/dist/util/adapter/adapters.d.ts +19 -0
- package/dist/util/adapter/filesystem.d.ts +20 -0
- package/dist/util/controller-scanner.d.ts +4 -0
- package/dist/util/cpu-monitor.d.ts +2 -0
- package/dist/util/middleware-tracker.d.ts +10 -0
- package/dist/util/types.d.ts +37 -0
- package/package.json +5 -5
- package/dist/analyzer.impl-CV6W1Eq7.js.map +0 -1
- package/dist/analyzer.impl-D9Yi1Hax.cjs.map +0 -1
- package/dist/http-server-BEMPIs33.cjs +0 -85
- package/dist/http-server-BEMPIs33.cjs.map +0 -1
- package/dist/http-server-CCeagTyU.js +0 -68
- package/dist/http-server-CCeagTyU.js.map +0 -1
- package/dist/plugins/application/dashboard/static/poll.js +0 -146
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http-server-CCeagTyU.js","sources":["../src/plugins/application/http-server.ts"],"sourcesContent":["import type { Server } from \"bun\";\nimport * as http from \"node:http\";\nimport * as https from \"node:https\";\nimport type { ServerFactory } from \"../../util/types\";\n\n/**\n * Creates a server factory that uses the standard Node.js `http` module.\n * @returns A ServerFactory compatible with Shokupan.\n */\nexport function createHttpServer(): ServerFactory {\n return async (options: any): Promise<Server<any>> => {\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url!, `http://${req.headers.host}`);\n const request = new Request(url.toString(), {\n method: req.method,\n headers: req.headers as any,\n body: ['GET', 'HEAD'].includes(req.method!) ? undefined : new ReadableStream({\n start(controller) {\n req.on('data', chunk => controller.enqueue(chunk));\n req.on('end', () => controller.close());\n req.on('error', err => controller.error(err));\n }\n }) as any,\n // Required for Node.js undici when sending a body\n duplex: 'half'\n } as any);\n\n const response = await options.fetch(request, fauxServer);\n\n res.statusCode = response.status;\n response.headers.forEach((v, k) => res.setHeader(k, v));\n\n if (response.body) {\n // Optimize: Use arrayBuffer for direct conversion instead of async iteration\n const buffer = await response.arrayBuffer();\n res.end(Buffer.from(buffer));\n } else {\n res.end();\n }\n });\n\n const fauxServer: Server<any> = {\n stop: () => {\n server.close();\n return Promise.resolve(); // Bun.Server stop usually returns void but in type definition it might vary.\n },\n upgrade(req, options) {\n return false;\n },\n reload(options) {\n return fauxServer as any;\n },\n get port() {\n const addr = server.address();\n if (typeof addr === 'object' && addr !== null) {\n return addr.port;\n }\n return options.port;\n },\n hostname: options.hostname,\n development: options.development,\n pendingRequests: 0,\n requestIP: (req) => null,\n publish: () => 0,\n subscriberCount: () => 0,\n url: new URL(`http://${options.hostname}:${options.port}`),\n // Expose the raw Node.js server for generic socket/websocket support (e.g. Socket.IO)\n nodeServer: server\n } as unknown as Server<any>;\n\n return new Promise((resolve) => {\n server.listen(options.port, options.hostname, () => {\n resolve(fauxServer);\n });\n });\n };\n}\n\n/**\n * Creates a server factory that uses the standard Node.js `https` module.\n * @param sslOptions - Node.js HTTPS options (key, cert, etc.)\n * @returns A ServerFactory compatible with Shokupan.\n */\nexport function createHttpsServer(sslOptions: https.ServerOptions): ServerFactory {\n return async (options: any): Promise<Server<any>> => {\n const server = https.createServer(sslOptions, async (req, res) => {\n const url = new URL(req.url!, `https://${req.headers.host}`);\n const request = new Request(url.toString(), {\n method: req.method,\n headers: req.headers as any,\n body: ['GET', 'HEAD'].includes(req.method!) ? undefined : new ReadableStream({\n start(controller) {\n req.on('data', chunk => controller.enqueue(chunk));\n req.on('end', () => controller.close());\n req.on('error', err => controller.error(err));\n }\n }) as any,\n // Required for Node.js undici when sending a body\n duplex: 'half'\n } as any);\n\n const response = await options.fetch(request, fauxServer);\n\n res.statusCode = response.status;\n response.headers.forEach((v, k) => res.setHeader(k, v));\n\n if (response.body) {\n // Optimize: Use arrayBuffer for direct conversion instead of async iteration\n const buffer = await response.arrayBuffer();\n res.end(Buffer.from(buffer));\n } else {\n res.end();\n }\n });\n\n const fauxServer: Server<any> = {\n stop: () => {\n server.close();\n },\n upgrade(req, options) {\n return false;\n },\n reload(options) {\n return fauxServer as any;\n },\n get port() {\n const addr = server.address();\n if (typeof addr === 'object' && addr !== null) {\n return addr.port;\n }\n return options.port;\n },\n hostname: options.hostname,\n development: options.development,\n pendingRequests: 0,\n requestIP: (req) => null,\n publish: () => 0,\n subscriberCount: () => 0,\n url: new URL(`https://${options.hostname}:${options.port}`),\n // Expose the raw Node.js server for generic socket/websocket support\n nodeServer: server\n } as unknown as Server<any>;\n\n return new Promise((resolve) => {\n server.listen(options.port, options.hostname, () => {\n resolve(fauxServer);\n });\n });\n };\n}\n"],"names":["options"],"mappings":";;AASO,SAAS,mBAAkC;AAC9C,SAAO,OAAO,YAAuC;AACjD,UAAM,SAAS,KAAK,aAAa,OAAO,KAAK,QAAQ;AACjD,YAAM,MAAM,IAAI,IAAI,IAAI,KAAM,UAAU,IAAI,QAAQ,IAAI,EAAE;AAC1D,YAAM,UAAU,IAAI,QAAQ,IAAI,YAAY;AAAA,QACxC,QAAQ,IAAI;AAAA,QACZ,SAAS,IAAI;AAAA,QACb,MAAM,CAAC,OAAO,MAAM,EAAE,SAAS,IAAI,MAAO,IAAI,SAAY,IAAI,eAAe;AAAA,UACzE,MAAM,YAAY;AACd,gBAAI,GAAG,QAAQ,CAAA,UAAS,WAAW,QAAQ,KAAK,CAAC;AACjD,gBAAI,GAAG,OAAO,MAAM,WAAW,OAAO;AACtC,gBAAI,GAAG,SAAS,CAAA,QAAO,WAAW,MAAM,GAAG,CAAC;AAAA,UAChD;AAAA,QAAA,CACH;AAAA;AAAA,QAED,QAAQ;AAAA,MAAA,CACJ;AAER,YAAM,WAAW,MAAM,QAAQ,MAAM,SAAS,UAAU;AAExD,UAAI,aAAa,SAAS;AAC1B,eAAS,QAAQ,QAAQ,CAAC,GAAG,MAAM,IAAI,UAAU,GAAG,CAAC,CAAC;AAEtD,UAAI,SAAS,MAAM;AAEf,cAAM,SAAS,MAAM,SAAS,YAAA;AAC9B,YAAI,IAAI,OAAO,KAAK,MAAM,CAAC;AAAA,MAC/B,OAAO;AACH,YAAI,IAAA;AAAA,MACR;AAAA,IACJ,CAAC;AAED,UAAM,aAA0B;AAAA,MAC5B,MAAM,MAAM;AACR,eAAO,MAAA;AACP,eAAO,QAAQ,QAAA;AAAA,MACnB;AAAA,MACA,QAAQ,KAAKA,UAAS;AAClB,eAAO;AAAA,MACX;AAAA,MACA,OAAOA,UAAS;AACZ,eAAO;AAAA,MACX;AAAA,MACA,IAAI,OAAO;AACP,cAAM,OAAO,OAAO,QAAA;AACpB,YAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC3C,iBAAO,KAAK;AAAA,QAChB;AACA,eAAO,QAAQ;AAAA,MACnB;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB,aAAa,QAAQ;AAAA,MACrB,iBAAiB;AAAA,MACjB,WAAW,CAAC,QAAQ;AAAA,MACpB,SAAS,MAAM;AAAA,MACf,iBAAiB,MAAM;AAAA,MACvB,KAAK,IAAI,IAAI,UAAU,QAAQ,QAAQ,IAAI,QAAQ,IAAI,EAAE;AAAA;AAAA,MAEzD,YAAY;AAAA,IAAA;AAGhB,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC5B,aAAO,OAAO,QAAQ,MAAM,QAAQ,UAAU,MAAM;AAChD,gBAAQ,UAAU;AAAA,MACtB,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AACJ;"}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
function printDuration(deltaMs/** number in ms */) {
|
|
3
|
-
|
|
4
|
-
// More than 1 week
|
|
5
|
-
if (deltaMs > (7 * 24 * 60 * 60 * 1000)) {
|
|
6
|
-
const weeks = (deltaMs / (7 * 24 * 60 * 60 * 1000));
|
|
7
|
-
const weeksR = (deltaMs % (7 * 24 * 60 * 60 * 1000));
|
|
8
|
-
|
|
9
|
-
if (weeks >= 10) {
|
|
10
|
-
return weeks.toFixed(0) + " weeks";
|
|
11
|
-
}
|
|
12
|
-
else {
|
|
13
|
-
const days = (weeksR / (24 * 60 * 60 * 1000));
|
|
14
|
-
|
|
15
|
-
if (days >= 1) {
|
|
16
|
-
return weeks.toFixed(0) + " weeks " + days.toFixed(0) + " days";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return weeks.toFixed(0) + " weeks";
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
// More than 1 day
|
|
23
|
-
else if (deltaMs > (24 * 60 * 60 * 1000)) {
|
|
24
|
-
const days = (deltaMs / (24 * 60 * 60 * 1000));
|
|
25
|
-
const daysR = (deltaMs % (24 * 60 * 60 * 1000));
|
|
26
|
-
|
|
27
|
-
if (days >= 10) {
|
|
28
|
-
return days.toFixed(0) + " days";
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
const hours = (daysR / (60 * 60 * 1000));
|
|
32
|
-
|
|
33
|
-
if (hours >= 1) {
|
|
34
|
-
return days.toFixed(0) + " days " + hours.toFixed(0) + " hours";
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return days.toFixed(0) + " days";
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// More than 1 hour
|
|
41
|
-
else if (deltaMs > (60 * 60 * 1000)) {
|
|
42
|
-
const hours = (deltaMs / (60 * 60 * 1000));
|
|
43
|
-
const hoursR = (deltaMs % (60 * 60 * 1000));
|
|
44
|
-
|
|
45
|
-
if (hours >= 10) {
|
|
46
|
-
return hours.toFixed(0) + " hours";
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
const minutes = (hoursR / (60 * 1000));
|
|
50
|
-
|
|
51
|
-
if (minutes >= 1) {
|
|
52
|
-
return hours.toFixed(0) + " hours " + minutes.toFixed(0) + " minutes";
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return hours.toFixed(0) + " hours";
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// less than an hour, print minutes
|
|
59
|
-
else if (deltaMs > 60 * 1000) {
|
|
60
|
-
const minutes = (deltaMs / (60 * 1000));
|
|
61
|
-
const minutesR = (deltaMs % (60 * 1000));
|
|
62
|
-
|
|
63
|
-
if (minutes >= 10) {
|
|
64
|
-
return minutes.toFixed(0) + " minutes";
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
const seconds = (minutesR / (1000));
|
|
68
|
-
|
|
69
|
-
if (seconds >= 1) {
|
|
70
|
-
return minutes.toFixed(0) + " minutes " + seconds.toFixed(0) + " seconds";
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return minutes.toFixed(0) + " minutes";
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
// Seconds (whoa)
|
|
77
|
-
else if (deltaMs > 1000) {
|
|
78
|
-
const seconds = (deltaMs / (60 * 1000));
|
|
79
|
-
|
|
80
|
-
if (seconds >= 10) {
|
|
81
|
-
return seconds.toFixed(0) + " seconds";
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return seconds.toFixed(2) + " seconds";
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Milliseconds
|
|
88
|
-
else if (deltaMs > 1) {
|
|
89
|
-
const ms = deltaMs;
|
|
90
|
-
return ms.toFixed(0) + " ms";
|
|
91
|
-
}
|
|
92
|
-
// Microseconds
|
|
93
|
-
else if (deltaMs > 0.0001) {
|
|
94
|
-
const us = deltaMs;
|
|
95
|
-
return us.toFixed(0) + " us";
|
|
96
|
-
}
|
|
97
|
-
else return "N/A";
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async function updateDashboard() {
|
|
101
|
-
try {
|
|
102
|
-
const headers = getRequestHeaders ? getRequestHeaders() : {};
|
|
103
|
-
const interval = document.getElementById('time-range-selector')?.value || '1m';
|
|
104
|
-
// Handle relative path issue when accessing /admin without trailing slash
|
|
105
|
-
const metricsUrl = (window.location.pathname.endsWith('/') ? 'metrics' : window.location.pathname + '/metrics') + `?interval=${interval}`;
|
|
106
|
-
const res = await fetch(metricsUrl, { headers });
|
|
107
|
-
if (!res.ok) return;
|
|
108
|
-
|
|
109
|
-
const data = await res.json();
|
|
110
|
-
const metrics = data.metrics;
|
|
111
|
-
window.metrics = metrics; // Update global metrics for tooltips
|
|
112
|
-
|
|
113
|
-
// Refresh Registry if active
|
|
114
|
-
if (document.getElementById('tab-registry').classList.contains('active')) {
|
|
115
|
-
const registryContainer = document.getElementById('registry-tree');
|
|
116
|
-
// Simple clear and re-render (optimization: could just update tooltips)
|
|
117
|
-
registryContainer.innerHTML = '';
|
|
118
|
-
window.renderRegistry(window.registryData, registryContainer);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
document.getElementById('uptime').innerText = data.uptime;
|
|
122
|
-
document.getElementById('total-requests').innerText = metrics.totalRequests;
|
|
123
|
-
document.getElementById('active-requests').innerText = metrics.activeRequests;
|
|
124
|
-
document.getElementById('successful-requests').innerText = metrics.successfulRequests;
|
|
125
|
-
document.getElementById('failed-requests').innerText = metrics.failedRequests;
|
|
126
|
-
document.getElementById('avg-latency').innerText = metrics.averageTotalTime_ms.toFixed(2);
|
|
127
|
-
|
|
128
|
-
// Recalc rates
|
|
129
|
-
const finishedRequests = metrics.totalRequests - metrics.activeRequests;
|
|
130
|
-
const successRate = finishedRequests ? Math.round((metrics.successfulRequests / finishedRequests) * 100) : 100;
|
|
131
|
-
const failRate = finishedRequests ? Math.round((metrics.failedRequests / finishedRequests) * 100) : 0;
|
|
132
|
-
|
|
133
|
-
document.getElementById('success-rate').innerText = successRate + '%';
|
|
134
|
-
document.getElementById('fail-rate').innerText = failRate + '%';
|
|
135
|
-
|
|
136
|
-
} catch (err) {
|
|
137
|
-
console.error("Failed to update dashboard", err);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Auto-refresh every 2 seconds
|
|
142
|
-
setInterval(updateDashboard, 2000);
|
|
143
|
-
// Initial load
|
|
144
|
-
updateDashboard();
|
|
145
|
-
|
|
146
|
-
|