@yuhere/js-jsonrpc2 2.1.12 → 2.1.13
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/cli/cli.d.ts +0 -1
- package/dist/cli/cli.js +0 -1
- package/dist/cli/demo-methods.d.ts +0 -1
- package/dist/cli/demo-methods.js +0 -1
- package/dist/cli/express.d.ts +0 -1
- package/dist/cli/express.js +0 -1
- package/dist/cli/stdio.d.ts +0 -1
- package/dist/cli/stdio.js +0 -1
- package/dist/core/Repository.d.ts +0 -1
- package/dist/core/Repository.js +0 -1
- package/dist/core/convert.d.ts +0 -1
- package/dist/core/convert.js +0 -1
- package/dist/core/descriptor.d.ts +0 -1
- package/dist/core/descriptor.js +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.js +0 -1
- package/dist/core/llm-tools.d.ts +0 -1
- package/dist/core/llm-tools.js +0 -1
- package/dist/core/permission.d.ts +0 -1
- package/dist/core/permission.js +0 -1
- package/dist/core/spec-check.d.ts +0 -1
- package/dist/core/spec-check.js +0 -1
- package/dist/core/system-methods.d.ts +0 -1
- package/dist/core/system-methods.js +0 -1
- package/dist/errors/RPCError.d.ts +0 -1
- package/dist/errors/RPCError.js +0 -1
- package/dist/errors/codes.d.ts +0 -1
- package/dist/errors/codes.js +0 -1
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/metrics/memory.d.ts +0 -1
- package/dist/metrics/memory.js +0 -1
- package/dist/metrics/prom.d.ts +0 -1
- package/dist/metrics/prom.js +0 -1
- package/dist/schema/json/index.d.ts +0 -1
- package/dist/schema/json/index.js +0 -1
- package/dist/schema/json/marker.d.ts +0 -1
- package/dist/schema/json/marker.js +0 -1
- package/dist/schema/json/primitives.d.ts +0 -1
- package/dist/schema/json/primitives.js +0 -1
- package/dist/schema/z/protocol.d.ts +0 -1
- package/dist/schema/z/protocol.js +0 -1
- package/dist/schema/z/register.d.ts +0 -1
- package/dist/schema/z/register.js +0 -1
- package/dist/stream/stringify-stream.d.ts +0 -1
- package/dist/stream/stringify-stream.js +94 -70
- package/dist/transport/express/body.d.ts +0 -1
- package/dist/transport/express/body.js +0 -1
- package/dist/transport/express/index.d.ts +0 -1
- package/dist/transport/express/index.js +0 -1
- package/dist/transport/express/middleware.d.ts +0 -1
- package/dist/transport/express/middleware.js +0 -1
- package/dist/transport/express/respond.d.ts +0 -1
- package/dist/transport/express/respond.js +0 -1
- package/dist/transport/stdio/index.d.ts +0 -1
- package/dist/transport/stdio/index.js +0 -1
- package/dist/transport/stdio/middleware.d.ts +0 -1
- package/dist/transport/stdio/middleware.js +0 -1
- package/dist/transport/ws/index.d.ts +0 -1
- package/dist/transport/ws/index.js +0 -1
- package/dist/transport/ws/middleware.d.ts +0 -1
- package/dist/transport/ws/middleware.js +0 -1
- package/dist/transport/ws/standalone.d.ts +0 -1
- package/dist/transport/ws/standalone.js +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -1
- package/dist/webclient/webui/src/client/httpTransport.d.ts +8 -0
- package/dist/webclient/webui/src/client/httpTransport.js +114 -0
- package/dist/webclient/webui/src/client/index.d.ts +4 -0
- package/dist/webclient/webui/src/client/index.js +2 -0
- package/dist/webclient/webui/src/client/rpc.d.ts +24 -0
- package/dist/webclient/webui/src/client/rpc.js +32 -0
- package/dist/webclient/webui/src/client/types.d.ts +14 -0
- package/dist/webclient/webui/src/client/types.js +1 -0
- package/dist/webclient/webui/src/client/wsTransport.d.ts +8 -0
- package/{webui/src/api/wsTransport.ts → dist/webclient/webui/src/client/wsTransport.js} +263 -305
- package/htdoc/assets/favicon-CXdFuLlv.png +0 -0
- package/htdoc/assets/{index-Cr0Jnrgb.js → index-CqI7vRAS.js} +1191 -327
- package/htdoc/assets/index-CqI7vRAS.js.map +1 -0
- package/{webui/src/styles/geek.css → htdoc/assets/index-Rq1yIwo2.css} +58 -0
- package/htdoc/index.html +4 -2
- package/package.json +10 -7
- package/dist/cli/cli.d.ts.map +0 -1
- package/dist/cli/cli.js.map +0 -1
- package/dist/cli/demo-methods.d.ts.map +0 -1
- package/dist/cli/demo-methods.js.map +0 -1
- package/dist/cli/express.d.ts.map +0 -1
- package/dist/cli/express.js.map +0 -1
- package/dist/cli/stdio.d.ts.map +0 -1
- package/dist/cli/stdio.js.map +0 -1
- package/dist/core/Repository.d.ts.map +0 -1
- package/dist/core/Repository.js.map +0 -1
- package/dist/core/convert.d.ts.map +0 -1
- package/dist/core/convert.js.map +0 -1
- package/dist/core/descriptor.d.ts.map +0 -1
- package/dist/core/descriptor.js.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/llm-tools.d.ts.map +0 -1
- package/dist/core/llm-tools.js.map +0 -1
- package/dist/core/permission.d.ts.map +0 -1
- package/dist/core/permission.js.map +0 -1
- package/dist/core/spec-check.d.ts.map +0 -1
- package/dist/core/spec-check.js.map +0 -1
- package/dist/core/system-methods.d.ts.map +0 -1
- package/dist/core/system-methods.js.map +0 -1
- package/dist/errors/RPCError.d.ts.map +0 -1
- package/dist/errors/RPCError.js.map +0 -1
- package/dist/errors/codes.d.ts.map +0 -1
- package/dist/errors/codes.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/metrics/memory.d.ts.map +0 -1
- package/dist/metrics/memory.js.map +0 -1
- package/dist/metrics/prom.d.ts.map +0 -1
- package/dist/metrics/prom.js.map +0 -1
- package/dist/schema/json/index.d.ts.map +0 -1
- package/dist/schema/json/index.js.map +0 -1
- package/dist/schema/json/marker.d.ts.map +0 -1
- package/dist/schema/json/marker.js.map +0 -1
- package/dist/schema/json/primitives.d.ts.map +0 -1
- package/dist/schema/json/primitives.js.map +0 -1
- package/dist/schema/z/protocol.d.ts.map +0 -1
- package/dist/schema/z/protocol.js.map +0 -1
- package/dist/schema/z/register.d.ts.map +0 -1
- package/dist/schema/z/register.js.map +0 -1
- package/dist/stream/stringify-stream.d.ts.map +0 -1
- package/dist/stream/stringify-stream.js.map +0 -1
- package/dist/transport/express/body.d.ts.map +0 -1
- package/dist/transport/express/body.js.map +0 -1
- package/dist/transport/express/index.d.ts.map +0 -1
- package/dist/transport/express/index.js.map +0 -1
- package/dist/transport/express/middleware.d.ts.map +0 -1
- package/dist/transport/express/middleware.js.map +0 -1
- package/dist/transport/express/respond.d.ts.map +0 -1
- package/dist/transport/express/respond.js.map +0 -1
- package/dist/transport/stdio/index.d.ts.map +0 -1
- package/dist/transport/stdio/index.js.map +0 -1
- package/dist/transport/stdio/middleware.d.ts.map +0 -1
- package/dist/transport/stdio/middleware.js.map +0 -1
- package/dist/transport/ws/index.d.ts.map +0 -1
- package/dist/transport/ws/index.js.map +0 -1
- package/dist/transport/ws/middleware.d.ts.map +0 -1
- package/dist/transport/ws/middleware.js.map +0 -1
- package/dist/transport/ws/standalone.d.ts.map +0 -1
- package/dist/transport/ws/standalone.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/htdoc/assets/index-Ck-39Igh.css +0 -963
- package/htdoc/assets/index-Cr0Jnrgb.js.map +0 -1
- package/webui/index.html +0 -12
- package/webui/src/App.tsx +0 -164
- package/webui/src/api/docGen.ts +0 -188
- package/webui/src/api/glob.ts +0 -90
- package/webui/src/api/httpTransport.ts +0 -148
- package/webui/src/api/metrics.ts +0 -135
- package/webui/src/api/paramForm.ts +0 -80
- package/webui/src/api/rpc.ts +0 -57
- package/webui/src/api/schema.ts +0 -12
- package/webui/src/api/types.ts +0 -16
- package/webui/src/components/MethodDetail.tsx +0 -43
- package/webui/src/components/MethodTree.tsx +0 -118
- package/webui/src/components/MetricsPanel.md +0 -126
- package/webui/src/components/MetricsPanel.tsx +0 -290
- package/webui/src/components/SchemaForm.tsx +0 -697
- package/webui/src/components/SchemaView.tsx +0 -151
- package/webui/src/components/TestPanel.tsx +0 -322
- package/webui/src/components/Toolbar.tsx +0 -82
- package/webui/src/hooks/useMethodDetail.ts +0 -61
- package/webui/src/hooks/useMethods.ts +0 -27
- package/webui/src/hooks/useMetrics.ts +0 -91
- package/webui/src/main.tsx +0 -13
- package/webui/src/theme/ThemeProvider.tsx +0 -79
- package/webui/src/vite-env.d.ts +0 -1
- package/webui/tsconfig.json +0 -34
- package/webui/tsconfig.node.json +0 -13
- package/webui/vite.config.ts +0 -15
|
@@ -7537,9 +7537,7 @@ var require_client = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
7537
7537
|
exports.hydrateRoot = m.hydrateRoot;
|
|
7538
7538
|
}));
|
|
7539
7539
|
//#endregion
|
|
7540
|
-
//#region webui/src/
|
|
7541
|
-
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
7542
|
-
var import_client = /* @__PURE__ */ __toESM(require_client(), 1);
|
|
7540
|
+
//#region webui/src/client/httpTransport.ts
|
|
7543
7541
|
var idCounter$1 = 0;
|
|
7544
7542
|
async function readLine(reader, decoder, state) {
|
|
7545
7543
|
while (true) {
|
|
@@ -7562,7 +7560,7 @@ async function readLine(reader, decoder, state) {
|
|
|
7562
7560
|
function isStreamFrame$1(v) {
|
|
7563
7561
|
return !!v && typeof v === "object" && typeof v.done === "boolean";
|
|
7564
7562
|
}
|
|
7565
|
-
function
|
|
7563
|
+
function createHttpRPC(options = {}) {
|
|
7566
7564
|
const { endpoint = "", headers = {}, fetchImpl = fetch } = options;
|
|
7567
7565
|
function call(method, ...params) {
|
|
7568
7566
|
const body = {
|
|
@@ -7576,7 +7574,7 @@ function createHttpRpc(options = {}) {
|
|
|
7576
7574
|
method: "POST",
|
|
7577
7575
|
headers: {
|
|
7578
7576
|
"Content-Type": "application/json",
|
|
7579
|
-
"Accept": "application/x-ndjson",
|
|
7577
|
+
"Accept": "application/json, application/x-ndjson",
|
|
7580
7578
|
...headers
|
|
7581
7579
|
},
|
|
7582
7580
|
body: JSON.stringify(body)
|
|
@@ -7643,7 +7641,7 @@ function absoluteEndpoint(endpoint) {
|
|
|
7643
7641
|
}
|
|
7644
7642
|
}
|
|
7645
7643
|
//#endregion
|
|
7646
|
-
//#region webui/src/
|
|
7644
|
+
//#region webui/src/client/wsTransport.ts
|
|
7647
7645
|
var idCounter = 0;
|
|
7648
7646
|
function deriveWsEndpoint() {
|
|
7649
7647
|
const loc = window.location;
|
|
@@ -7652,7 +7650,7 @@ function deriveWsEndpoint() {
|
|
|
7652
7650
|
function isStreamFrame(v) {
|
|
7653
7651
|
return !!v && typeof v === "object" && typeof v.done === "boolean";
|
|
7654
7652
|
}
|
|
7655
|
-
function
|
|
7653
|
+
function createWsRPC(options = {}) {
|
|
7656
7654
|
const { endpoint = deriveWsEndpoint(), connectTimeoutMs = 5e3, callTimeoutMs = 15e3 } = options;
|
|
7657
7655
|
const pending = /* @__PURE__ */ new Map();
|
|
7658
7656
|
const streams = /* @__PURE__ */ new Map();
|
|
@@ -7688,6 +7686,7 @@ function createWsRpc(options = {}) {
|
|
|
7688
7686
|
}
|
|
7689
7687
|
const list = Array.isArray(data) ? data : [data];
|
|
7690
7688
|
for (const msg of list) {
|
|
7689
|
+
if (!msg || typeof msg !== "object") continue;
|
|
7691
7690
|
if (msg.id == null) continue;
|
|
7692
7691
|
const fw = firstWaiters.get(msg.id);
|
|
7693
7692
|
if (fw) {
|
|
@@ -7902,7 +7901,7 @@ function _defineProperty(e, r, t) {
|
|
|
7902
7901
|
}) : e[r] = t, e;
|
|
7903
7902
|
}
|
|
7904
7903
|
//#endregion
|
|
7905
|
-
//#region webui/src/
|
|
7904
|
+
//#region webui/src/client/rpc.ts
|
|
7906
7905
|
var RPCError = class extends Error {
|
|
7907
7906
|
constructor(payload) {
|
|
7908
7907
|
super(payload.message);
|
|
@@ -7920,13 +7919,13 @@ var RPCError = class extends Error {
|
|
|
7920
7919
|
function isStreamResult(v) {
|
|
7921
7920
|
return !!v && typeof v === "object" && typeof v[Symbol.asyncIterator] === "function";
|
|
7922
7921
|
}
|
|
7923
|
-
function
|
|
7924
|
-
if (options.transport === "ws") return
|
|
7922
|
+
function createRPC(options) {
|
|
7923
|
+
if (options.transport === "ws") return createWsRPC({
|
|
7925
7924
|
endpoint: options.endpoint,
|
|
7926
7925
|
connectTimeoutMs: options.connectTimeoutMs,
|
|
7927
7926
|
callTimeoutMs: options.callTimeoutMs
|
|
7928
7927
|
});
|
|
7929
|
-
return
|
|
7928
|
+
return createHttpRPC({
|
|
7930
7929
|
endpoint: options.endpoint,
|
|
7931
7930
|
headers: options.headers,
|
|
7932
7931
|
fetchImpl: options.fetchImpl
|
|
@@ -7934,6 +7933,8 @@ function createRpc(options) {
|
|
|
7934
7933
|
}
|
|
7935
7934
|
//#endregion
|
|
7936
7935
|
//#region webui/src/hooks/useMethods.ts
|
|
7936
|
+
var import_client = /* @__PURE__ */ __toESM(require_client(), 1);
|
|
7937
|
+
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
7937
7938
|
function useMethods(rpc) {
|
|
7938
7939
|
const [methods, setMethods] = (0, import_react.useState)([]);
|
|
7939
7940
|
const [loading, setLoading] = (0, import_react.useState)(false);
|
|
@@ -8013,6 +8014,24 @@ function useMethodDetail(rpc, method) {
|
|
|
8013
8014
|
return detail;
|
|
8014
8015
|
}
|
|
8015
8016
|
//#endregion
|
|
8017
|
+
//#region webui/src/hooks/useDebouncedValue.ts
|
|
8018
|
+
/**
|
|
8019
|
+
* 返回 `value` 的防抖版本:`value` 停止变化 `delayMs` 毫秒后才更新返回值。
|
|
8020
|
+
* 初始值立即生效(首次渲染不会延迟)。
|
|
8021
|
+
*/
|
|
8022
|
+
function useDebouncedValue(value, delayMs = 250) {
|
|
8023
|
+
const [debounced, setDebounced] = (0, import_react.useState)(value);
|
|
8024
|
+
(0, import_react.useEffect)(() => {
|
|
8025
|
+
if (delayMs <= 0) {
|
|
8026
|
+
setDebounced(value);
|
|
8027
|
+
return;
|
|
8028
|
+
}
|
|
8029
|
+
const t = setTimeout(() => setDebounced(value), delayMs);
|
|
8030
|
+
return () => clearTimeout(t);
|
|
8031
|
+
}, [value, delayMs]);
|
|
8032
|
+
return debounced;
|
|
8033
|
+
}
|
|
8034
|
+
//#endregion
|
|
8016
8035
|
//#region webui/src/api/metrics.ts
|
|
8017
8036
|
/** 拉取 system.metrics;如果系统方法不可用(withSystemMethods=false),返回 undefined。 */
|
|
8018
8037
|
async function fetchMetrics(rpc) {
|
|
@@ -8187,11 +8206,11 @@ var require_react_jsx_runtime_production_min = /* @__PURE__ */ __commonJSMin(((e
|
|
|
8187
8206
|
var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
8188
8207
|
module.exports = require_react_jsx_runtime_production_min();
|
|
8189
8208
|
})))();
|
|
8190
|
-
var STORAGE_KEY = "jsonrpc2.theme";
|
|
8209
|
+
var STORAGE_KEY$1 = "jsonrpc2.theme";
|
|
8191
8210
|
var ThemeContext = (0, import_react.createContext)(null);
|
|
8192
|
-
function readStoredMode() {
|
|
8211
|
+
function readStoredMode$1() {
|
|
8193
8212
|
try {
|
|
8194
|
-
const v = localStorage.getItem(STORAGE_KEY);
|
|
8213
|
+
const v = localStorage.getItem(STORAGE_KEY$1);
|
|
8195
8214
|
if (v === "light" || v === "dark" || v === "system") return v;
|
|
8196
8215
|
} catch {}
|
|
8197
8216
|
return "system";
|
|
@@ -8200,7 +8219,7 @@ function prefersDark() {
|
|
|
8200
8219
|
return typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
8201
8220
|
}
|
|
8202
8221
|
function ThemeProvider({ children }) {
|
|
8203
|
-
const [mode, setModeState] = (0, import_react.useState)(readStoredMode);
|
|
8222
|
+
const [mode, setModeState] = (0, import_react.useState)(readStoredMode$1);
|
|
8204
8223
|
const [systemDark, setSystemDark] = (0, import_react.useState)(prefersDark);
|
|
8205
8224
|
(0, import_react.useEffect)(() => {
|
|
8206
8225
|
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
@@ -8219,7 +8238,7 @@ function ThemeProvider({ children }) {
|
|
|
8219
8238
|
(0, import_react.useEffect)(() => {
|
|
8220
8239
|
document.documentElement.setAttribute("data-theme", resolved);
|
|
8221
8240
|
try {
|
|
8222
|
-
localStorage.setItem(STORAGE_KEY, mode);
|
|
8241
|
+
localStorage.setItem(STORAGE_KEY$1, mode);
|
|
8223
8242
|
} catch {}
|
|
8224
8243
|
}, [resolved, mode]);
|
|
8225
8244
|
const setMode = (0, import_react.useCallback)((m) => setModeState(m), []);
|
|
@@ -8242,54 +8261,812 @@ function useTheme() {
|
|
|
8242
8261
|
if (!ctx) throw new Error("useTheme must be used within <ThemeProvider>");
|
|
8243
8262
|
return ctx;
|
|
8244
8263
|
}
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8264
|
+
var MESSAGES = {
|
|
8265
|
+
en: {
|
|
8266
|
+
common: {
|
|
8267
|
+
loading: "Loading…",
|
|
8268
|
+
refresh: "Refresh",
|
|
8269
|
+
refreshing: "Refreshing…",
|
|
8270
|
+
reset: "Reset",
|
|
8271
|
+
clear: "Clear",
|
|
8272
|
+
delete: "Delete",
|
|
8273
|
+
add: "Add",
|
|
8274
|
+
copy: "Copy",
|
|
8275
|
+
copied: "Copied ✓",
|
|
8276
|
+
copyFailed: "Copy failed: {error}",
|
|
8277
|
+
generate: "Generate",
|
|
8278
|
+
generating: "Generating…",
|
|
8279
|
+
none: "None",
|
|
8280
|
+
empty: "Empty"
|
|
8281
|
+
},
|
|
8282
|
+
toolbar: {
|
|
8283
|
+
title: "JSON-RPC 2.0",
|
|
8284
|
+
transport: "Transport",
|
|
8285
|
+
http: "HTTP",
|
|
8286
|
+
ws: "WebSocket",
|
|
8287
|
+
refreshMethods: "Refresh methods",
|
|
8288
|
+
refreshMethodsLoading: "Refreshing…",
|
|
8289
|
+
generateDocs: "Generate docs ⬇",
|
|
8290
|
+
generateDocsLoading: "Generating…",
|
|
8291
|
+
generateDocsTitle: "Fetch help and signatures of all methods, render Markdown and download",
|
|
8292
|
+
theme: "Theme",
|
|
8293
|
+
themeSystem: "System",
|
|
8294
|
+
themeLight: "Light",
|
|
8295
|
+
themeDark: "Dark",
|
|
8296
|
+
language: "Language",
|
|
8297
|
+
languageSystem: "Follow system",
|
|
8298
|
+
languageEn: "English",
|
|
8299
|
+
languageZhCN: "简体中文",
|
|
8300
|
+
languageZhTW: "繁體中文",
|
|
8301
|
+
languageJa: "日本語"
|
|
8302
|
+
},
|
|
8303
|
+
sidebar: {
|
|
8304
|
+
methods: "Methods",
|
|
8305
|
+
metrics: "Metrics",
|
|
8306
|
+
search: "Search",
|
|
8307
|
+
searchPlaceholder: "Type keywords, space separated",
|
|
8308
|
+
matchCount: "Matched {matched} / {total} methods",
|
|
8309
|
+
noMatch: "No matching methods.",
|
|
8310
|
+
noMethods: "No methods available."
|
|
8311
|
+
},
|
|
8312
|
+
view: {
|
|
8313
|
+
label: "View",
|
|
8314
|
+
methods: "Methods",
|
|
8315
|
+
metrics: "Metrics"
|
|
8316
|
+
},
|
|
8317
|
+
method: {
|
|
8318
|
+
selectHint: "← Select a method from the left to view help and signature.",
|
|
8319
|
+
loading: "Loading…",
|
|
8320
|
+
loadFailed: "Load failed: {error}",
|
|
8321
|
+
help: "Help",
|
|
8322
|
+
noHelp: "(no help available)",
|
|
8323
|
+
returnType: "Return type",
|
|
8324
|
+
returnTypeHint: "(the server does not validate execution results against this type; actual values may differ)",
|
|
8325
|
+
none: "(none)"
|
|
8326
|
+
},
|
|
8327
|
+
test: {
|
|
8328
|
+
params: "Parameters",
|
|
8329
|
+
paramsHint: "({count}, auto-generated from signature)",
|
|
8330
|
+
noParams: "This method takes no parameters.",
|
|
8331
|
+
execute: "Execute ▶",
|
|
8332
|
+
executing: "Executing…",
|
|
8333
|
+
executeStream: "Execute & receive stream ▶",
|
|
8334
|
+
receiving: "Receiving…",
|
|
8335
|
+
resetToSample: "Reset to sample",
|
|
8336
|
+
clearOutput: "Clear output",
|
|
8337
|
+
result: "Result",
|
|
8338
|
+
resultStream: " (streaming)",
|
|
8339
|
+
notExecuted: "(not executed yet)",
|
|
8340
|
+
copyCurl: "Copy curl (bash)",
|
|
8341
|
+
copyCurlCmd: "Copy curl (cmd)",
|
|
8342
|
+
copyFetch: "Copy fetch",
|
|
8343
|
+
copyTitle: "Copy equivalent code for current call",
|
|
8344
|
+
copyDisabledTitle: "Only HTTP transport can generate code",
|
|
8345
|
+
chooseFormat: "Choose format",
|
|
8346
|
+
streamEnded: "(stream ended, {count} frames, total {duration})",
|
|
8347
|
+
streamEndedEmpty: "(stream ended, no data, total {duration})",
|
|
8348
|
+
elapsed: "elapsed",
|
|
8349
|
+
firstFrame: "first frame",
|
|
8350
|
+
jsonError: "JSON error: {error}"
|
|
8351
|
+
},
|
|
8352
|
+
schema: {
|
|
8353
|
+
nullable: "nullable",
|
|
8354
|
+
setNull: "Set null",
|
|
8355
|
+
fillValue: "Fill value",
|
|
8356
|
+
fixedValue: "(fixed value)",
|
|
8357
|
+
unionNoBranch: "(union has no branch)",
|
|
8358
|
+
arrayNoItem: "(array has no item schema)",
|
|
8359
|
+
recordNoValue: "(record has no value schema)",
|
|
8360
|
+
recordAddPlaceholder: "New key",
|
|
8361
|
+
addRecordKey: "+ Add key",
|
|
8362
|
+
addItem: "+ Add item",
|
|
8363
|
+
strictHint: "(non-strict mode, extra fields allowed)",
|
|
8364
|
+
paramIndex: "Parameter [{index}]",
|
|
8365
|
+
items: "items",
|
|
8366
|
+
values: "values",
|
|
8367
|
+
optionIndex: "option[{index}]",
|
|
8368
|
+
inner: "inner"
|
|
8369
|
+
},
|
|
8370
|
+
metrics: {
|
|
8371
|
+
title: "Metrics",
|
|
8372
|
+
unavailable: "Server did not enable system.metrics (withSystemMethods: false or not registered).",
|
|
8373
|
+
autoRefresh: "Auto refresh",
|
|
8374
|
+
interval: "Interval",
|
|
8375
|
+
refreshNow: "Refresh now",
|
|
8376
|
+
refreshing: "Refreshing…",
|
|
8377
|
+
uptime: "uptime",
|
|
8378
|
+
loading: "Loading…",
|
|
8379
|
+
methods: "Methods",
|
|
8380
|
+
calls: "Calls",
|
|
8381
|
+
streams: "Streams",
|
|
8382
|
+
errors: "Errors",
|
|
8383
|
+
errorRate: "Error rate",
|
|
8384
|
+
invalidRequests: "Invalid requests",
|
|
8385
|
+
nonStreamTitle: "Non-stream methods",
|
|
8386
|
+
streamTitle: "Stream methods",
|
|
8387
|
+
noData: "No data.",
|
|
8388
|
+
noStreams: "No streaming calls.",
|
|
8389
|
+
countHint: " ({count})",
|
|
8390
|
+
colMethod: "method",
|
|
8391
|
+
colCalls: "calls",
|
|
8392
|
+
colRate: "rate/s",
|
|
8393
|
+
colErrors: "errors",
|
|
8394
|
+
colErrPct: "err%",
|
|
8395
|
+
colP50: "p50",
|
|
8396
|
+
colP95: "p95",
|
|
8397
|
+
colP99: "p99",
|
|
8398
|
+
colAvg: "avg",
|
|
8399
|
+
colOpened: "opened",
|
|
8400
|
+
colCompleted: "completed",
|
|
8401
|
+
colFailed: "failed",
|
|
8402
|
+
colAborted: "aborted",
|
|
8403
|
+
colCompletePct: "complete%",
|
|
8404
|
+
colAbortPct: "abort%",
|
|
8405
|
+
colAvgChunks: "avg chunks",
|
|
8406
|
+
colTtfbP50: "ttfb p50",
|
|
8407
|
+
colTtfbP95: "ttfb p95",
|
|
8408
|
+
colDurationAvg: "duration avg"
|
|
8409
|
+
},
|
|
8410
|
+
footer: {
|
|
8411
|
+
version: "version",
|
|
8412
|
+
npm: "npm package",
|
|
8413
|
+
github: "GitHub repository"
|
|
8414
|
+
},
|
|
8415
|
+
alerts: {
|
|
8416
|
+
emptyMethods: "Method list is empty. Please refresh methods first.",
|
|
8417
|
+
docsFailed: "Failed to generate docs: {error}"
|
|
8418
|
+
}
|
|
8419
|
+
},
|
|
8420
|
+
"zh-CN": {
|
|
8421
|
+
common: {
|
|
8422
|
+
loading: "加载中…",
|
|
8423
|
+
refresh: "刷新",
|
|
8424
|
+
refreshing: "刷新中…",
|
|
8425
|
+
reset: "重置",
|
|
8426
|
+
clear: "清空",
|
|
8427
|
+
delete: "删除",
|
|
8428
|
+
add: "添加",
|
|
8429
|
+
copy: "复制",
|
|
8430
|
+
copied: "已复制 ✓",
|
|
8431
|
+
copyFailed: "复制失败:{error}",
|
|
8432
|
+
generate: "生成",
|
|
8433
|
+
generating: "生成中…",
|
|
8434
|
+
none: "无",
|
|
8435
|
+
empty: "空"
|
|
8436
|
+
},
|
|
8437
|
+
toolbar: {
|
|
8438
|
+
title: "JSON-RPC 2.0",
|
|
8439
|
+
transport: "传输方式",
|
|
8440
|
+
http: "HTTP",
|
|
8441
|
+
ws: "WebSocket",
|
|
8442
|
+
refreshMethods: "刷新方法列表",
|
|
8443
|
+
refreshMethodsLoading: "刷新中…",
|
|
8444
|
+
generateDocs: "生成文档 ⬇",
|
|
8445
|
+
generateDocsLoading: "生成中…",
|
|
8446
|
+
generateDocsTitle: "拉取所有方法的帮助与签名,生成 Markdown 文档并下载",
|
|
8447
|
+
theme: "主题",
|
|
8448
|
+
themeSystem: "跟随系统",
|
|
8449
|
+
themeLight: "亮",
|
|
8450
|
+
themeDark: "暗",
|
|
8451
|
+
language: "语言",
|
|
8452
|
+
languageSystem: "跟随系统语言",
|
|
8453
|
+
languageEn: "English",
|
|
8454
|
+
languageZhCN: "简体中文",
|
|
8455
|
+
languageZhTW: "繁體中文",
|
|
8456
|
+
languageJa: "日本語"
|
|
8457
|
+
},
|
|
8458
|
+
sidebar: {
|
|
8459
|
+
methods: "Methods",
|
|
8460
|
+
metrics: "Metrics",
|
|
8461
|
+
search: "搜索",
|
|
8462
|
+
searchPlaceholder: "输入关键词,空格分隔",
|
|
8463
|
+
matchCount: "匹配 {matched} / {total} 个方法",
|
|
8464
|
+
noMatch: "没有匹配的方法。",
|
|
8465
|
+
noMethods: "暂无可用方法。"
|
|
8466
|
+
},
|
|
8467
|
+
view: {
|
|
8468
|
+
label: "视图",
|
|
8469
|
+
methods: "Methods",
|
|
8470
|
+
metrics: "Metrics"
|
|
8471
|
+
},
|
|
8472
|
+
method: {
|
|
8473
|
+
selectHint: "← 从左侧选择一个方法查看帮助与签名。",
|
|
8474
|
+
loading: "加载中…",
|
|
8475
|
+
loadFailed: "加载失败:{error}",
|
|
8476
|
+
help: "Help",
|
|
8477
|
+
noHelp: "(无帮助信息)",
|
|
8478
|
+
returnType: "返回类型",
|
|
8479
|
+
returnTypeHint: "(服务端不会校验执行结果是否符合此类型,实际返回值可能会有所不同)",
|
|
8480
|
+
none: "(暂无)"
|
|
8481
|
+
},
|
|
8482
|
+
test: {
|
|
8483
|
+
params: "参数",
|
|
8484
|
+
paramsHint: "({count} 个,按签名自动生成)",
|
|
8485
|
+
noParams: "此方法无需参数。",
|
|
8486
|
+
execute: "执行 ▶",
|
|
8487
|
+
executing: "执行中…",
|
|
8488
|
+
executeStream: "执行并接收流 ▶",
|
|
8489
|
+
receiving: "接收中…",
|
|
8490
|
+
resetToSample: "重置为示例",
|
|
8491
|
+
clearOutput: "清空输出",
|
|
8492
|
+
result: "结果",
|
|
8493
|
+
resultStream: "(流式)",
|
|
8494
|
+
notExecuted: "(尚未执行)",
|
|
8495
|
+
copyCurl: "复制 curl (bash)",
|
|
8496
|
+
copyCurlCmd: "复制 curl (cmd)",
|
|
8497
|
+
copyFetch: "复制 fetch",
|
|
8498
|
+
copyTitle: "复制当前调用的等价代码",
|
|
8499
|
+
copyDisabledTitle: "仅 HTTP 传输可生成代码",
|
|
8500
|
+
chooseFormat: "选择复制格式",
|
|
8501
|
+
streamEnded: "(流已结束,共 {count} 帧,总耗时 {duration})",
|
|
8502
|
+
streamEndedEmpty: "(流已结束,无数据,总耗时 {duration})",
|
|
8503
|
+
elapsed: "耗时",
|
|
8504
|
+
firstFrame: "首帧",
|
|
8505
|
+
jsonError: "JSON 错误:{error}"
|
|
8506
|
+
},
|
|
8507
|
+
schema: {
|
|
8508
|
+
nullable: "nullable",
|
|
8509
|
+
setNull: "置 null",
|
|
8510
|
+
fillValue: "填值",
|
|
8511
|
+
fixedValue: "(固定值)",
|
|
8512
|
+
unionNoBranch: "(union 无分支)",
|
|
8513
|
+
arrayNoItem: "(数组无 item schema)",
|
|
8514
|
+
recordNoValue: "(record 无 value schema)",
|
|
8515
|
+
recordAddPlaceholder: "新键名",
|
|
8516
|
+
addRecordKey: "+ 添加键",
|
|
8517
|
+
addItem: "+ 添加项",
|
|
8518
|
+
strictHint: "(非 strict 模式,允许额外字段)",
|
|
8519
|
+
paramIndex: "参数 [{index}]",
|
|
8520
|
+
items: "items",
|
|
8521
|
+
values: "values",
|
|
8522
|
+
optionIndex: "option[{index}]",
|
|
8523
|
+
inner: "inner"
|
|
8524
|
+
},
|
|
8525
|
+
metrics: {
|
|
8526
|
+
title: "Metrics",
|
|
8527
|
+
unavailable: "服务端未启用 system.metrics(withSystemMethods: false 或未注册)。",
|
|
8528
|
+
autoRefresh: "自动刷新",
|
|
8529
|
+
interval: "刷新间隔",
|
|
8530
|
+
refreshNow: "立即刷新",
|
|
8531
|
+
refreshing: "刷新中…",
|
|
8532
|
+
uptime: "uptime",
|
|
8533
|
+
loading: "加载中…",
|
|
8534
|
+
methods: "Methods",
|
|
8535
|
+
calls: "Calls",
|
|
8536
|
+
streams: "Streams",
|
|
8537
|
+
errors: "Errors",
|
|
8538
|
+
errorRate: "Error rate",
|
|
8539
|
+
invalidRequests: "Invalid requests",
|
|
8540
|
+
nonStreamTitle: "Non-stream methods",
|
|
8541
|
+
streamTitle: "Stream methods",
|
|
8542
|
+
noData: "暂无数据。",
|
|
8543
|
+
noStreams: "暂无流式调用。",
|
|
8544
|
+
countHint: "({count})",
|
|
8545
|
+
colMethod: "method",
|
|
8546
|
+
colCalls: "calls",
|
|
8547
|
+
colRate: "rate/s",
|
|
8548
|
+
colErrors: "errors",
|
|
8549
|
+
colErrPct: "err%",
|
|
8550
|
+
colP50: "p50",
|
|
8551
|
+
colP95: "p95",
|
|
8552
|
+
colP99: "p99",
|
|
8553
|
+
colAvg: "avg",
|
|
8554
|
+
colOpened: "opened",
|
|
8555
|
+
colCompleted: "completed",
|
|
8556
|
+
colFailed: "failed",
|
|
8557
|
+
colAborted: "aborted",
|
|
8558
|
+
colCompletePct: "complete%",
|
|
8559
|
+
colAbortPct: "abort%",
|
|
8560
|
+
colAvgChunks: "avg chunks",
|
|
8561
|
+
colTtfbP50: "ttfb p50",
|
|
8562
|
+
colTtfbP95: "ttfb p95",
|
|
8563
|
+
colDurationAvg: "duration avg"
|
|
8564
|
+
},
|
|
8565
|
+
footer: {
|
|
8566
|
+
version: "版本",
|
|
8567
|
+
npm: "npm 包",
|
|
8568
|
+
github: "GitHub 仓库"
|
|
8569
|
+
},
|
|
8570
|
+
alerts: {
|
|
8571
|
+
emptyMethods: "方法列表为空,请先刷新方法列表。",
|
|
8572
|
+
docsFailed: "生成文档失败:{error}"
|
|
8573
|
+
}
|
|
8251
8574
|
},
|
|
8252
|
-
{
|
|
8253
|
-
|
|
8254
|
-
|
|
8575
|
+
"zh-TW": {
|
|
8576
|
+
common: {
|
|
8577
|
+
loading: "載入中…",
|
|
8578
|
+
refresh: "重新整理",
|
|
8579
|
+
refreshing: "重新整理中…",
|
|
8580
|
+
reset: "重設",
|
|
8581
|
+
clear: "清除",
|
|
8582
|
+
delete: "刪除",
|
|
8583
|
+
add: "新增",
|
|
8584
|
+
copy: "複製",
|
|
8585
|
+
copied: "已複製 ✓",
|
|
8586
|
+
copyFailed: "複製失敗:{error}",
|
|
8587
|
+
generate: "產生",
|
|
8588
|
+
generating: "產生中…",
|
|
8589
|
+
none: "無",
|
|
8590
|
+
empty: "空"
|
|
8591
|
+
},
|
|
8592
|
+
toolbar: {
|
|
8593
|
+
title: "JSON-RPC 2.0",
|
|
8594
|
+
transport: "傳輸方式",
|
|
8595
|
+
http: "HTTP",
|
|
8596
|
+
ws: "WebSocket",
|
|
8597
|
+
refreshMethods: "重新整理方法清單",
|
|
8598
|
+
refreshMethodsLoading: "重新整理中…",
|
|
8599
|
+
generateDocs: "產生文件 ⬇",
|
|
8600
|
+
generateDocsLoading: "產生中…",
|
|
8601
|
+
generateDocsTitle: "取得所有方法的說明與簽章,產生 Markdown 文件並下載",
|
|
8602
|
+
theme: "主題",
|
|
8603
|
+
themeSystem: "跟隨系統",
|
|
8604
|
+
themeLight: "亮",
|
|
8605
|
+
themeDark: "暗",
|
|
8606
|
+
language: "語言",
|
|
8607
|
+
languageSystem: "跟隨系統語言",
|
|
8608
|
+
languageEn: "English",
|
|
8609
|
+
languageZhCN: "简体中文",
|
|
8610
|
+
languageZhTW: "繁體中文",
|
|
8611
|
+
languageJa: "日本語"
|
|
8612
|
+
},
|
|
8613
|
+
sidebar: {
|
|
8614
|
+
methods: "Methods",
|
|
8615
|
+
metrics: "Metrics",
|
|
8616
|
+
search: "搜尋",
|
|
8617
|
+
searchPlaceholder: "輸入關鍵字,以空格分隔",
|
|
8618
|
+
matchCount: "符合 {matched} / {total} 個方法",
|
|
8619
|
+
noMatch: "沒有符合的方法。",
|
|
8620
|
+
noMethods: "尚無可用方法。"
|
|
8621
|
+
},
|
|
8622
|
+
view: {
|
|
8623
|
+
label: "檢視",
|
|
8624
|
+
methods: "Methods",
|
|
8625
|
+
metrics: "Metrics"
|
|
8626
|
+
},
|
|
8627
|
+
method: {
|
|
8628
|
+
selectHint: "← 從左側選擇一個方法以檢視說明與簽章。",
|
|
8629
|
+
loading: "載入中…",
|
|
8630
|
+
loadFailed: "載入失敗:{error}",
|
|
8631
|
+
help: "Help",
|
|
8632
|
+
noHelp: "(無說明資訊)",
|
|
8633
|
+
returnType: "回傳型別",
|
|
8634
|
+
returnTypeHint: "(伺服器不會驗證執行結果是否符合此型別,實際回傳值可能有所不同)",
|
|
8635
|
+
none: "(暫無)"
|
|
8636
|
+
},
|
|
8637
|
+
test: {
|
|
8638
|
+
params: "參數",
|
|
8639
|
+
paramsHint: "({count} 個,依簽章自動產生)",
|
|
8640
|
+
noParams: "此方法無需參數。",
|
|
8641
|
+
execute: "執行 ▶",
|
|
8642
|
+
executing: "執行中…",
|
|
8643
|
+
executeStream: "執行並接收串流 ▶",
|
|
8644
|
+
receiving: "接收中…",
|
|
8645
|
+
resetToSample: "重設為範例",
|
|
8646
|
+
clearOutput: "清除輸出",
|
|
8647
|
+
result: "結果",
|
|
8648
|
+
resultStream: "(串流)",
|
|
8649
|
+
notExecuted: "(尚未執行)",
|
|
8650
|
+
copyCurl: "複製 curl (bash)",
|
|
8651
|
+
copyCurlCmd: "複製 curl (cmd)",
|
|
8652
|
+
copyFetch: "複製 fetch",
|
|
8653
|
+
copyTitle: "複製目前呼叫的等效程式碼",
|
|
8654
|
+
copyDisabledTitle: "僅 HTTP 傳輸可產生程式碼",
|
|
8655
|
+
chooseFormat: "選擇複製格式",
|
|
8656
|
+
streamEnded: "(串流已結束,共 {count} 幀,總耗時 {duration})",
|
|
8657
|
+
streamEndedEmpty: "(串流已結束,無資料,總耗時 {duration})",
|
|
8658
|
+
elapsed: "耗時",
|
|
8659
|
+
firstFrame: "首幀",
|
|
8660
|
+
jsonError: "JSON 錯誤:{error}"
|
|
8661
|
+
},
|
|
8662
|
+
schema: {
|
|
8663
|
+
nullable: "nullable",
|
|
8664
|
+
setNull: "設為 null",
|
|
8665
|
+
fillValue: "填入值",
|
|
8666
|
+
fixedValue: "(固定值)",
|
|
8667
|
+
unionNoBranch: "(union 無分支)",
|
|
8668
|
+
arrayNoItem: "(陣列無 item schema)",
|
|
8669
|
+
recordNoValue: "(record 無 value schema)",
|
|
8670
|
+
recordAddPlaceholder: "新鍵名",
|
|
8671
|
+
addRecordKey: "+ 新增鍵",
|
|
8672
|
+
addItem: "+ 新增項目",
|
|
8673
|
+
strictHint: "(非 strict 模式,允許額外欄位)",
|
|
8674
|
+
paramIndex: "參數 [{index}]",
|
|
8675
|
+
items: "items",
|
|
8676
|
+
values: "values",
|
|
8677
|
+
optionIndex: "option[{index}]",
|
|
8678
|
+
inner: "inner"
|
|
8679
|
+
},
|
|
8680
|
+
metrics: {
|
|
8681
|
+
title: "Metrics",
|
|
8682
|
+
unavailable: "伺服器未啟用 system.metrics(withSystemMethods: false 或未註冊)。",
|
|
8683
|
+
autoRefresh: "自動重新整理",
|
|
8684
|
+
interval: "重新整理間隔",
|
|
8685
|
+
refreshNow: "立即重新整理",
|
|
8686
|
+
refreshing: "重新整理中…",
|
|
8687
|
+
uptime: "uptime",
|
|
8688
|
+
loading: "載入中…",
|
|
8689
|
+
methods: "Methods",
|
|
8690
|
+
calls: "Calls",
|
|
8691
|
+
streams: "Streams",
|
|
8692
|
+
errors: "Errors",
|
|
8693
|
+
errorRate: "Error rate",
|
|
8694
|
+
invalidRequests: "Invalid requests",
|
|
8695
|
+
nonStreamTitle: "Non-stream methods",
|
|
8696
|
+
streamTitle: "Stream methods",
|
|
8697
|
+
noData: "尚無資料。",
|
|
8698
|
+
noStreams: "尚無串流呼叫。",
|
|
8699
|
+
countHint: "({count})",
|
|
8700
|
+
colMethod: "method",
|
|
8701
|
+
colCalls: "calls",
|
|
8702
|
+
colRate: "rate/s",
|
|
8703
|
+
colErrors: "errors",
|
|
8704
|
+
colErrPct: "err%",
|
|
8705
|
+
colP50: "p50",
|
|
8706
|
+
colP95: "p95",
|
|
8707
|
+
colP99: "p99",
|
|
8708
|
+
colAvg: "avg",
|
|
8709
|
+
colOpened: "opened",
|
|
8710
|
+
colCompleted: "completed",
|
|
8711
|
+
colFailed: "failed",
|
|
8712
|
+
colAborted: "aborted",
|
|
8713
|
+
colCompletePct: "complete%",
|
|
8714
|
+
colAbortPct: "abort%",
|
|
8715
|
+
colAvgChunks: "avg chunks",
|
|
8716
|
+
colTtfbP50: "ttfb p50",
|
|
8717
|
+
colTtfbP95: "ttfb p95",
|
|
8718
|
+
colDurationAvg: "duration avg"
|
|
8719
|
+
},
|
|
8720
|
+
footer: {
|
|
8721
|
+
version: "版本",
|
|
8722
|
+
npm: "npm 套件",
|
|
8723
|
+
github: "GitHub 儲存庫"
|
|
8724
|
+
},
|
|
8725
|
+
alerts: {
|
|
8726
|
+
emptyMethods: "方法清單為空,請先重新整理方法清單。",
|
|
8727
|
+
docsFailed: "產生文件失敗:{error}"
|
|
8728
|
+
}
|
|
8255
8729
|
},
|
|
8256
|
-
{
|
|
8257
|
-
|
|
8258
|
-
|
|
8730
|
+
ja: {
|
|
8731
|
+
common: {
|
|
8732
|
+
loading: "読み込み中…",
|
|
8733
|
+
refresh: "更新",
|
|
8734
|
+
refreshing: "更新中…",
|
|
8735
|
+
reset: "リセット",
|
|
8736
|
+
clear: "クリア",
|
|
8737
|
+
delete: "削除",
|
|
8738
|
+
add: "追加",
|
|
8739
|
+
copy: "コピー",
|
|
8740
|
+
copied: "コピーしました ✓",
|
|
8741
|
+
copyFailed: "コピーに失敗しました:{error}",
|
|
8742
|
+
generate: "生成",
|
|
8743
|
+
generating: "生成中…",
|
|
8744
|
+
none: "なし",
|
|
8745
|
+
empty: "空"
|
|
8746
|
+
},
|
|
8747
|
+
toolbar: {
|
|
8748
|
+
title: "JSON-RPC 2.0",
|
|
8749
|
+
transport: "トランスポート",
|
|
8750
|
+
http: "HTTP",
|
|
8751
|
+
ws: "WebSocket",
|
|
8752
|
+
refreshMethods: "メソッド一覧を更新",
|
|
8753
|
+
refreshMethodsLoading: "更新中…",
|
|
8754
|
+
generateDocs: "ドキュメント生成 ⬇",
|
|
8755
|
+
generateDocsLoading: "生成中…",
|
|
8756
|
+
generateDocsTitle: "全メソッドのヘルプとシグネチャを取得し、Markdown を生成してダウンロード",
|
|
8757
|
+
theme: "テーマ",
|
|
8758
|
+
themeSystem: "システムに従う",
|
|
8759
|
+
themeLight: "ライト",
|
|
8760
|
+
themeDark: "ダーク",
|
|
8761
|
+
language: "言語",
|
|
8762
|
+
languageSystem: "システム言語に従う",
|
|
8763
|
+
languageEn: "English",
|
|
8764
|
+
languageZhCN: "简体中文",
|
|
8765
|
+
languageZhTW: "繁體中文",
|
|
8766
|
+
languageJa: "日本語"
|
|
8767
|
+
},
|
|
8768
|
+
sidebar: {
|
|
8769
|
+
methods: "Methods",
|
|
8770
|
+
metrics: "Metrics",
|
|
8771
|
+
search: "検索",
|
|
8772
|
+
searchPlaceholder: "キーワードを入力(スペース区切り)",
|
|
8773
|
+
matchCount: "{matched} / {total} 件のメソッドが一致",
|
|
8774
|
+
noMatch: "一致するメソッドはありません。",
|
|
8775
|
+
noMethods: "利用可能なメソッドがありません。"
|
|
8776
|
+
},
|
|
8777
|
+
view: {
|
|
8778
|
+
label: "ビュー",
|
|
8779
|
+
methods: "Methods",
|
|
8780
|
+
metrics: "Metrics"
|
|
8781
|
+
},
|
|
8782
|
+
method: {
|
|
8783
|
+
selectHint: "← 左側からメソッドを選択すると、ヘルプとシグネチャが表示されます。",
|
|
8784
|
+
loading: "読み込み中…",
|
|
8785
|
+
loadFailed: "読み込み失敗:{error}",
|
|
8786
|
+
help: "Help",
|
|
8787
|
+
noHelp: "(ヘルプ情報なし)",
|
|
8788
|
+
returnType: "戻り値の型",
|
|
8789
|
+
returnTypeHint: "(サーバーは実行結果がこの型に一致するか検証しません。実際の戻り値は異なる場合があります)",
|
|
8790
|
+
none: "(なし)"
|
|
8791
|
+
},
|
|
8792
|
+
test: {
|
|
8793
|
+
params: "パラメータ",
|
|
8794
|
+
paramsHint: "({count} 個、シグネチャから自動生成)",
|
|
8795
|
+
noParams: "このメソッドはパラメータを取りません。",
|
|
8796
|
+
execute: "実行 ▶",
|
|
8797
|
+
executing: "実行中…",
|
|
8798
|
+
executeStream: "実行してストリーム受信 ▶",
|
|
8799
|
+
receiving: "受信中…",
|
|
8800
|
+
resetToSample: "サンプルに戻す",
|
|
8801
|
+
clearOutput: "出力をクリア",
|
|
8802
|
+
result: "結果",
|
|
8803
|
+
resultStream: "(ストリーミング)",
|
|
8804
|
+
notExecuted: "(未実行)",
|
|
8805
|
+
copyCurl: "curl をコピー (bash)",
|
|
8806
|
+
copyCurlCmd: "curl をコピー (cmd)",
|
|
8807
|
+
copyFetch: "fetch をコピー",
|
|
8808
|
+
copyTitle: "現在の呼び出しに相当するコードをコピー",
|
|
8809
|
+
copyDisabledTitle: "コード生成は HTTP トランスポートのみ対応",
|
|
8810
|
+
chooseFormat: "コピー形式を選択",
|
|
8811
|
+
streamEnded: "(ストリーム終了、{count} フレーム、合計 {duration})",
|
|
8812
|
+
streamEndedEmpty: "(ストリーム終了、データなし、合計 {duration})",
|
|
8813
|
+
elapsed: "経過",
|
|
8814
|
+
firstFrame: "初回フレーム",
|
|
8815
|
+
jsonError: "JSON エラー:{error}"
|
|
8816
|
+
},
|
|
8817
|
+
schema: {
|
|
8818
|
+
nullable: "nullable",
|
|
8819
|
+
setNull: "null にする",
|
|
8820
|
+
fillValue: "値を入力",
|
|
8821
|
+
fixedValue: "(固定値)",
|
|
8822
|
+
unionNoBranch: "(union に分岐がありません)",
|
|
8823
|
+
arrayNoItem: "(配列に item schema がありません)",
|
|
8824
|
+
recordNoValue: "(record に value schema がありません)",
|
|
8825
|
+
recordAddPlaceholder: "新しいキー",
|
|
8826
|
+
addRecordKey: "+ キーを追加",
|
|
8827
|
+
addItem: "+ 項目を追加",
|
|
8828
|
+
strictHint: "(非 strict モード、追加フィールドを許可)",
|
|
8829
|
+
paramIndex: "パラメータ [{index}]",
|
|
8830
|
+
items: "items",
|
|
8831
|
+
values: "values",
|
|
8832
|
+
optionIndex: "option[{index}]",
|
|
8833
|
+
inner: "inner"
|
|
8834
|
+
},
|
|
8835
|
+
metrics: {
|
|
8836
|
+
title: "Metrics",
|
|
8837
|
+
unavailable: "サーバーで system.metrics が有効になっていません(withSystemMethods: false または未登録)。",
|
|
8838
|
+
autoRefresh: "自動更新",
|
|
8839
|
+
interval: "更新間隔",
|
|
8840
|
+
refreshNow: "今すぐ更新",
|
|
8841
|
+
refreshing: "更新中…",
|
|
8842
|
+
uptime: "uptime",
|
|
8843
|
+
loading: "読み込み中…",
|
|
8844
|
+
methods: "Methods",
|
|
8845
|
+
calls: "Calls",
|
|
8846
|
+
streams: "Streams",
|
|
8847
|
+
errors: "Errors",
|
|
8848
|
+
errorRate: "Error rate",
|
|
8849
|
+
invalidRequests: "Invalid requests",
|
|
8850
|
+
nonStreamTitle: "Non-stream methods",
|
|
8851
|
+
streamTitle: "Stream methods",
|
|
8852
|
+
noData: "データがありません。",
|
|
8853
|
+
noStreams: "ストリーミング呼び出しはありません。",
|
|
8854
|
+
countHint: "({count})",
|
|
8855
|
+
colMethod: "method",
|
|
8856
|
+
colCalls: "calls",
|
|
8857
|
+
colRate: "rate/s",
|
|
8858
|
+
colErrors: "errors",
|
|
8859
|
+
colErrPct: "err%",
|
|
8860
|
+
colP50: "p50",
|
|
8861
|
+
colP95: "p95",
|
|
8862
|
+
colP99: "p99",
|
|
8863
|
+
colAvg: "avg",
|
|
8864
|
+
colOpened: "opened",
|
|
8865
|
+
colCompleted: "completed",
|
|
8866
|
+
colFailed: "failed",
|
|
8867
|
+
colAborted: "aborted",
|
|
8868
|
+
colCompletePct: "complete%",
|
|
8869
|
+
colAbortPct: "abort%",
|
|
8870
|
+
colAvgChunks: "avg chunks",
|
|
8871
|
+
colTtfbP50: "ttfb p50",
|
|
8872
|
+
colTtfbP95: "ttfb p95",
|
|
8873
|
+
colDurationAvg: "duration avg"
|
|
8874
|
+
},
|
|
8875
|
+
footer: {
|
|
8876
|
+
version: "バージョン",
|
|
8877
|
+
npm: "npm パッケージ",
|
|
8878
|
+
github: "GitHub リポジトリ"
|
|
8879
|
+
},
|
|
8880
|
+
alerts: {
|
|
8881
|
+
emptyMethods: "メソッド一覧が空です。先にメソッド一覧を更新してください。",
|
|
8882
|
+
docsFailed: "ドキュメント生成に失敗しました:{error}"
|
|
8883
|
+
}
|
|
8259
8884
|
}
|
|
8885
|
+
};
|
|
8886
|
+
//#endregion
|
|
8887
|
+
//#region webui/src/i18n/detect.ts
|
|
8888
|
+
/** 把 BCP-47 语言标签映射到我们支持的 4 种 locale。 */
|
|
8889
|
+
function normalizeLocale(tag) {
|
|
8890
|
+
if (!tag) return void 0;
|
|
8891
|
+
const t = tag.toLowerCase();
|
|
8892
|
+
if (t === "ja" || t.startsWith("ja-")) return "ja";
|
|
8893
|
+
if (t === "zh" || t.startsWith("zh-")) {
|
|
8894
|
+
if (t.includes("hant") || t.startsWith("zh-tw") || t.startsWith("zh-hk") || t.startsWith("zh-mo")) return "zh-TW";
|
|
8895
|
+
return "zh-CN";
|
|
8896
|
+
}
|
|
8897
|
+
if (t === "en" || t.startsWith("en-")) return "en";
|
|
8898
|
+
}
|
|
8899
|
+
/** 读取浏览器语言偏好,取第一个能映射的;否则回退 en。 */
|
|
8900
|
+
function detectSystemLocale() {
|
|
8901
|
+
const nav = typeof navigator !== "undefined" ? navigator : void 0;
|
|
8902
|
+
const candidates = [];
|
|
8903
|
+
if (nav?.languages && nav.languages.length > 0) candidates.push(...nav.languages);
|
|
8904
|
+
if (nav?.language) candidates.push(nav.language);
|
|
8905
|
+
for (const c of candidates) {
|
|
8906
|
+
const loc = normalizeLocale(c);
|
|
8907
|
+
if (loc) return loc;
|
|
8908
|
+
}
|
|
8909
|
+
return "en";
|
|
8910
|
+
}
|
|
8911
|
+
//#endregion
|
|
8912
|
+
//#region webui/src/i18n/I18nProvider.tsx
|
|
8913
|
+
var STORAGE_KEY = "jsonrpc2.locale";
|
|
8914
|
+
var I18nContext = (0, import_react.createContext)(null);
|
|
8915
|
+
var VALID_MODES = [
|
|
8916
|
+
"system",
|
|
8917
|
+
"en",
|
|
8918
|
+
"zh-CN",
|
|
8919
|
+
"zh-TW",
|
|
8920
|
+
"ja"
|
|
8260
8921
|
];
|
|
8922
|
+
function readStoredMode() {
|
|
8923
|
+
try {
|
|
8924
|
+
const v = localStorage.getItem(STORAGE_KEY);
|
|
8925
|
+
if (v && VALID_MODES.includes(v)) return v;
|
|
8926
|
+
} catch {}
|
|
8927
|
+
return "system";
|
|
8928
|
+
}
|
|
8929
|
+
function getByPath(obj, path) {
|
|
8930
|
+
const parts = path.split(".");
|
|
8931
|
+
let cur = obj;
|
|
8932
|
+
for (const p of parts) {
|
|
8933
|
+
if (cur == null || typeof cur !== "object") return void 0;
|
|
8934
|
+
cur = cur[p];
|
|
8935
|
+
}
|
|
8936
|
+
return cur;
|
|
8937
|
+
}
|
|
8938
|
+
function interpolate(text, vars) {
|
|
8939
|
+
if (!vars) return text;
|
|
8940
|
+
return text.replace(/\{(\w+)\}/g, (_, name) => {
|
|
8941
|
+
const v = vars[name];
|
|
8942
|
+
return v === void 0 ? `{${name}}` : String(v);
|
|
8943
|
+
});
|
|
8944
|
+
}
|
|
8945
|
+
function I18nProvider({ children }) {
|
|
8946
|
+
const [mode, setModeState] = (0, import_react.useState)(readStoredMode);
|
|
8947
|
+
const [systemLocale, setSystemLocale] = (0, import_react.useState)(detectSystemLocale);
|
|
8948
|
+
(0, import_react.useEffect)(() => {
|
|
8949
|
+
const onChange = () => setSystemLocale(detectSystemLocale());
|
|
8950
|
+
window.addEventListener("languagechange", onChange);
|
|
8951
|
+
return () => window.removeEventListener("languagechange", onChange);
|
|
8952
|
+
}, []);
|
|
8953
|
+
const locale = (0, import_react.useMemo)(() => {
|
|
8954
|
+
if (mode === "system") return systemLocale;
|
|
8955
|
+
return normalizeLocale(mode) ?? systemLocale;
|
|
8956
|
+
}, [mode, systemLocale]);
|
|
8957
|
+
(0, import_react.useEffect)(() => {
|
|
8958
|
+
document.documentElement.setAttribute("lang", locale);
|
|
8959
|
+
try {
|
|
8960
|
+
localStorage.setItem(STORAGE_KEY, mode);
|
|
8961
|
+
} catch {}
|
|
8962
|
+
}, [locale, mode]);
|
|
8963
|
+
const messages = MESSAGES[locale];
|
|
8964
|
+
const t = (0, import_react.useCallback)((key, vars) => {
|
|
8965
|
+
const raw = getByPath(messages, key);
|
|
8966
|
+
if (typeof raw === "string") return interpolate(raw, vars);
|
|
8967
|
+
const fallback = getByPath(MESSAGES.en, key);
|
|
8968
|
+
if (typeof fallback === "string") return interpolate(fallback, vars);
|
|
8969
|
+
return key;
|
|
8970
|
+
}, [messages]);
|
|
8971
|
+
const setMode = (0, import_react.useCallback)((m) => setModeState(m), []);
|
|
8972
|
+
const value = (0, import_react.useMemo)(() => ({
|
|
8973
|
+
mode,
|
|
8974
|
+
locale,
|
|
8975
|
+
messages,
|
|
8976
|
+
setMode,
|
|
8977
|
+
t
|
|
8978
|
+
}), [
|
|
8979
|
+
mode,
|
|
8980
|
+
locale,
|
|
8981
|
+
messages,
|
|
8982
|
+
setMode,
|
|
8983
|
+
t
|
|
8984
|
+
]);
|
|
8985
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(I18nContext.Provider, {
|
|
8986
|
+
value,
|
|
8987
|
+
children
|
|
8988
|
+
});
|
|
8989
|
+
}
|
|
8990
|
+
function useI18n() {
|
|
8991
|
+
const ctx = (0, import_react.useContext)(I18nContext);
|
|
8992
|
+
if (!ctx) throw new Error("useI18n must be used within <I18nProvider>");
|
|
8993
|
+
return ctx;
|
|
8994
|
+
}
|
|
8995
|
+
/** 便捷 hook:只取 t */
|
|
8996
|
+
function useT() {
|
|
8997
|
+
return useI18n().t;
|
|
8998
|
+
}
|
|
8999
|
+
//#endregion
|
|
9000
|
+
//#region webui/src/components/Toolbar.tsx
|
|
8261
9001
|
function Toolbar({ transport, onTransportChange, onRefresh, loading, error, onGenerateDocs, generatingDocs }) {
|
|
8262
9002
|
const { mode, setMode } = useTheme();
|
|
9003
|
+
const { t, mode: localeMode, setMode: setLocaleMode } = useI18n();
|
|
9004
|
+
const themeOptions = [
|
|
9005
|
+
{
|
|
9006
|
+
value: "system",
|
|
9007
|
+
label: t("toolbar.themeSystem")
|
|
9008
|
+
},
|
|
9009
|
+
{
|
|
9010
|
+
value: "light",
|
|
9011
|
+
label: t("toolbar.themeLight")
|
|
9012
|
+
},
|
|
9013
|
+
{
|
|
9014
|
+
value: "dark",
|
|
9015
|
+
label: t("toolbar.themeDark")
|
|
9016
|
+
}
|
|
9017
|
+
];
|
|
9018
|
+
const localeOptions = [
|
|
9019
|
+
{
|
|
9020
|
+
value: "system",
|
|
9021
|
+
label: t("toolbar.languageSystem")
|
|
9022
|
+
},
|
|
9023
|
+
{
|
|
9024
|
+
value: "en",
|
|
9025
|
+
label: t("toolbar.languageEn")
|
|
9026
|
+
},
|
|
9027
|
+
{
|
|
9028
|
+
value: "zh-CN",
|
|
9029
|
+
label: t("toolbar.languageZhCN")
|
|
9030
|
+
},
|
|
9031
|
+
{
|
|
9032
|
+
value: "zh-TW",
|
|
9033
|
+
label: t("toolbar.languageZhTW")
|
|
9034
|
+
},
|
|
9035
|
+
{
|
|
9036
|
+
value: "ja",
|
|
9037
|
+
label: t("toolbar.languageJa")
|
|
9038
|
+
}
|
|
9039
|
+
];
|
|
8263
9040
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
|
|
8264
9041
|
className: "toolbar",
|
|
8265
9042
|
children: [
|
|
8266
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: "
|
|
9043
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: t("toolbar.title") }),
|
|
8267
9044
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
8268
9045
|
className: "segmented",
|
|
8269
9046
|
role: "group",
|
|
8270
|
-
"aria-label": "
|
|
9047
|
+
"aria-label": t("toolbar.transport"),
|
|
8271
9048
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
8272
9049
|
type: "button",
|
|
8273
9050
|
className: transport === "http" ? "active" : "",
|
|
8274
9051
|
onClick: () => onTransportChange("http"),
|
|
8275
|
-
children: "
|
|
9052
|
+
children: t("toolbar.http")
|
|
8276
9053
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
8277
9054
|
type: "button",
|
|
8278
9055
|
className: transport === "ws" ? "active" : "",
|
|
8279
9056
|
onClick: () => onTransportChange("ws"),
|
|
8280
|
-
children: "
|
|
9057
|
+
children: t("toolbar.ws")
|
|
8281
9058
|
})]
|
|
8282
9059
|
}),
|
|
8283
9060
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
8284
9061
|
onClick: onRefresh,
|
|
8285
9062
|
disabled: loading,
|
|
8286
|
-
children: loading ? "
|
|
9063
|
+
children: loading ? t("toolbar.refreshMethodsLoading") : t("toolbar.refreshMethods")
|
|
8287
9064
|
}),
|
|
8288
9065
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
8289
9066
|
onClick: onGenerateDocs,
|
|
8290
|
-
disabled: generatingDocs || loading
|
|
8291
|
-
title: "
|
|
8292
|
-
children: generatingDocs ? "
|
|
9067
|
+
disabled: generatingDocs || loading,
|
|
9068
|
+
title: t("toolbar.generateDocsTitle"),
|
|
9069
|
+
children: generatingDocs ? t("toolbar.generateDocsLoading") : t("toolbar.generateDocs")
|
|
8293
9070
|
}),
|
|
8294
9071
|
error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
8295
9072
|
className: "error",
|
|
@@ -8297,14 +9074,29 @@ function Toolbar({ transport, onTransportChange, onRefresh, loading, error, onGe
|
|
|
8297
9074
|
}),
|
|
8298
9075
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
8299
9076
|
className: "theme-select",
|
|
8300
|
-
title: "
|
|
9077
|
+
title: t("toolbar.language"),
|
|
8301
9078
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
8302
9079
|
className: "theme-select-label",
|
|
8303
|
-
children: "
|
|
9080
|
+
children: t("toolbar.language")
|
|
9081
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
|
|
9082
|
+
value: localeMode,
|
|
9083
|
+
onChange: (e) => setLocaleMode(e.target.value),
|
|
9084
|
+
children: localeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
9085
|
+
value: opt.value,
|
|
9086
|
+
children: opt.label
|
|
9087
|
+
}, opt.value))
|
|
9088
|
+
})]
|
|
9089
|
+
}),
|
|
9090
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
9091
|
+
className: "theme-select",
|
|
9092
|
+
title: t("toolbar.theme"),
|
|
9093
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
9094
|
+
className: "theme-select-label",
|
|
9095
|
+
children: t("toolbar.theme")
|
|
8304
9096
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", {
|
|
8305
9097
|
value: mode,
|
|
8306
9098
|
onChange: (e) => setMode(e.target.value),
|
|
8307
|
-
children:
|
|
9099
|
+
children: themeOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
8308
9100
|
value: opt.value,
|
|
8309
9101
|
children: opt.label
|
|
8310
9102
|
}, opt.value))
|
|
@@ -8351,10 +9143,11 @@ function buildTree(methods) {
|
|
|
8351
9143
|
return root.children;
|
|
8352
9144
|
}
|
|
8353
9145
|
function MethodTree({ methods, selected, onSelect }) {
|
|
9146
|
+
const t = useT();
|
|
8354
9147
|
const tree = (0, import_react.useMemo)(() => buildTree(methods), [methods]);
|
|
8355
9148
|
if (methods.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8356
9149
|
className: "empty",
|
|
8357
|
-
children: "
|
|
9150
|
+
children: t("sidebar.noMethods")
|
|
8358
9151
|
});
|
|
8359
9152
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
8360
9153
|
className: "tree",
|
|
@@ -8424,6 +9217,7 @@ function formatConstraints$1(constraints) {
|
|
|
8424
9217
|
return entries.map(([k, v]) => `${k}=${typeof v === "string" ? JSON.stringify(v) : JSON.stringify(v)}`).join(", ");
|
|
8425
9218
|
}
|
|
8426
9219
|
function SchemaNode({ schema, depth, defaultOpen, label }) {
|
|
9220
|
+
const t = useT();
|
|
8427
9221
|
const [open, setOpen] = (0, import_react.useState)(defaultOpen);
|
|
8428
9222
|
const hasChildren = schema.children && Object.keys(schema.children).length > 0;
|
|
8429
9223
|
const constraintsText = formatConstraints$1(schema.constraints);
|
|
@@ -8471,17 +9265,18 @@ function SchemaNode({ schema, depth, defaultOpen, label }) {
|
|
|
8471
9265
|
]
|
|
8472
9266
|
}), open && hasChildren && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
8473
9267
|
className: "schema-children",
|
|
8474
|
-
children: renderChildren(schema, depth + 1)
|
|
9268
|
+
children: renderChildren(schema, depth + 1, t)
|
|
8475
9269
|
})]
|
|
8476
9270
|
});
|
|
8477
9271
|
}
|
|
8478
|
-
function renderChildren(schema, depth) {
|
|
9272
|
+
function renderChildren(schema, depth, t) {
|
|
8479
9273
|
const c = schema.children ?? {};
|
|
8480
9274
|
const out = [];
|
|
8481
9275
|
if (c.inner && isSchemaDescription(c.inner)) out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaNode, {
|
|
8482
9276
|
schema: c.inner,
|
|
8483
9277
|
depth,
|
|
8484
|
-
defaultOpen: true
|
|
9278
|
+
defaultOpen: true,
|
|
9279
|
+
label: t("schema.inner")
|
|
8485
9280
|
}, "inner"));
|
|
8486
9281
|
if (Array.isArray(c.items)) c.items.forEach((item, i) => {
|
|
8487
9282
|
if (isSchemaDescription(item)) out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaNode, {
|
|
@@ -8495,14 +9290,14 @@ function renderChildren(schema, depth) {
|
|
|
8495
9290
|
schema: c.items,
|
|
8496
9291
|
depth,
|
|
8497
9292
|
defaultOpen: true,
|
|
8498
|
-
label: "items"
|
|
9293
|
+
label: t("schema.items")
|
|
8499
9294
|
}, "items"));
|
|
8500
9295
|
if (Array.isArray(c.options)) c.options.forEach((opt, i) => {
|
|
8501
9296
|
if (isSchemaDescription(opt)) out.push(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaNode, {
|
|
8502
9297
|
schema: opt,
|
|
8503
9298
|
depth,
|
|
8504
9299
|
defaultOpen: false,
|
|
8505
|
-
label:
|
|
9300
|
+
label: t("schema.optionIndex", { index: i })
|
|
8506
9301
|
}, `opt-${i}`));
|
|
8507
9302
|
});
|
|
8508
9303
|
if (c.properties && typeof c.properties === "object" && !Array.isArray(c.properties)) {
|
|
@@ -8517,7 +9312,7 @@ function renderChildren(schema, depth) {
|
|
|
8517
9312
|
schema: c.values,
|
|
8518
9313
|
depth,
|
|
8519
9314
|
defaultOpen: true,
|
|
8520
|
-
label: "values"
|
|
9315
|
+
label: t("schema.values")
|
|
8521
9316
|
}, "values"));
|
|
8522
9317
|
return out;
|
|
8523
9318
|
}
|
|
@@ -8534,11 +9329,12 @@ function SchemaView({ schema, defaultOpen = true, depth = 0 }) {
|
|
|
8534
9329
|
//#endregion
|
|
8535
9330
|
//#region webui/src/components/MethodDetail.tsx
|
|
8536
9331
|
function MethodDetail({ method, detail }) {
|
|
9332
|
+
const t = useT();
|
|
8537
9333
|
if (!method) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", {
|
|
8538
9334
|
className: "detail",
|
|
8539
9335
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8540
9336
|
className: "hint",
|
|
8541
|
-
children: "
|
|
9337
|
+
children: t("method.selectHint")
|
|
8542
9338
|
})
|
|
8543
9339
|
});
|
|
8544
9340
|
const [returnSchema] = detail.signature;
|
|
@@ -8548,23 +9344,23 @@ function MethodDetail({ method, detail }) {
|
|
|
8548
9344
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: method }),
|
|
8549
9345
|
detail.loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8550
9346
|
className: "hint",
|
|
8551
|
-
children: "
|
|
9347
|
+
children: t("method.loading")
|
|
8552
9348
|
}),
|
|
8553
|
-
detail.error && /* @__PURE__ */ (0, import_jsx_runtime.
|
|
9349
|
+
detail.error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8554
9350
|
className: "error",
|
|
8555
|
-
children:
|
|
9351
|
+
children: t("method.loadFailed", { error: detail.error })
|
|
8556
9352
|
}),
|
|
8557
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "
|
|
9353
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: t("method.help") }),
|
|
8558
9354
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
|
|
8559
9355
|
className: "help",
|
|
8560
|
-
children: detail.help || "
|
|
9356
|
+
children: detail.help || t("method.noHelp")
|
|
8561
9357
|
}),
|
|
8562
9358
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
|
|
8563
|
-
"
|
|
9359
|
+
t("method.returnType"),
|
|
8564
9360
|
" ",
|
|
8565
9361
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
8566
9362
|
className: "hint",
|
|
8567
|
-
children: "
|
|
9363
|
+
children: t("method.returnTypeHint")
|
|
8568
9364
|
})
|
|
8569
9365
|
] }),
|
|
8570
9366
|
returnSchema ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaView, {
|
|
@@ -8573,7 +9369,7 @@ function MethodDetail({ method, detail }) {
|
|
|
8573
9369
|
defaultOpen: true
|
|
8574
9370
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8575
9371
|
className: "hint",
|
|
8576
|
-
children: "
|
|
9372
|
+
children: t("method.none")
|
|
8577
9373
|
})
|
|
8578
9374
|
]
|
|
8579
9375
|
});
|
|
@@ -8647,9 +9443,10 @@ function formatConstraints(c) {
|
|
|
8647
9443
|
return Object.entries(c).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(", ");
|
|
8648
9444
|
}
|
|
8649
9445
|
function SchemaForm({ params, values, onChange, disabled }) {
|
|
9446
|
+
const t = useT();
|
|
8650
9447
|
if (params.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8651
9448
|
className: "hint",
|
|
8652
|
-
children: "
|
|
9449
|
+
children: t("test.noParams")
|
|
8653
9450
|
});
|
|
8654
9451
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
8655
9452
|
className: "schema-form",
|
|
@@ -8657,13 +9454,14 @@ function SchemaForm({ params, values, onChange, disabled }) {
|
|
|
8657
9454
|
schema,
|
|
8658
9455
|
value: values[i],
|
|
8659
9456
|
onChange: (v) => onChange(i, v),
|
|
8660
|
-
label:
|
|
9457
|
+
label: t("schema.paramIndex", { index: i }),
|
|
8661
9458
|
depth: 0,
|
|
8662
9459
|
disabled
|
|
8663
9460
|
}, i))
|
|
8664
9461
|
});
|
|
8665
9462
|
}
|
|
8666
9463
|
function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen = true, disabled }) {
|
|
9464
|
+
const t = useT();
|
|
8667
9465
|
const [open, setOpen] = (0, import_react.useState)(defaultOpen);
|
|
8668
9466
|
const kind = schema.kind;
|
|
8669
9467
|
if (schema.nullable) {
|
|
@@ -8685,7 +9483,7 @@ function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen =
|
|
|
8685
9483
|
}),
|
|
8686
9484
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
8687
9485
|
className: "sf-nullable-badge",
|
|
8688
|
-
children: "nullable"
|
|
9486
|
+
children: t("schema.nullable")
|
|
8689
9487
|
}),
|
|
8690
9488
|
schema.description && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
8691
9489
|
className: "sf-desc",
|
|
@@ -8696,7 +9494,7 @@ function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen =
|
|
|
8696
9494
|
className: "tiny",
|
|
8697
9495
|
disabled,
|
|
8698
9496
|
onClick: () => onChange(null),
|
|
8699
|
-
children: "
|
|
9497
|
+
children: t("schema.setNull")
|
|
8700
9498
|
}),
|
|
8701
9499
|
isNull && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
8702
9500
|
type: "button",
|
|
@@ -8706,7 +9504,7 @@ function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen =
|
|
|
8706
9504
|
...schema,
|
|
8707
9505
|
nullable: false
|
|
8708
9506
|
})),
|
|
8709
|
-
children: "
|
|
9507
|
+
children: t("schema.fillValue")
|
|
8710
9508
|
})
|
|
8711
9509
|
]
|
|
8712
9510
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -8843,6 +9641,7 @@ function isScalarKind(kind) {
|
|
|
8843
9641
|
return kind === "string" || kind === "number" || kind === "boolean" || kind === "enum" || kind === "literal" || kind === "null";
|
|
8844
9642
|
}
|
|
8845
9643
|
function ScalarInput({ schema, value, onChange, disabled }) {
|
|
9644
|
+
const t = useT();
|
|
8846
9645
|
switch (schema.kind) {
|
|
8847
9646
|
case "boolean": return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
8848
9647
|
className: "sf-scalar",
|
|
@@ -8880,7 +9679,7 @@ function ScalarInput({ schema, value, onChange, disabled }) {
|
|
|
8880
9679
|
children: JSON.stringify(schema.constraints?.value ?? null)
|
|
8881
9680
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
8882
9681
|
className: "hint",
|
|
8883
|
-
children: "
|
|
9682
|
+
children: t("schema.fixedValue")
|
|
8884
9683
|
})]
|
|
8885
9684
|
});
|
|
8886
9685
|
case "null": return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -8890,7 +9689,7 @@ function ScalarInput({ schema, value, onChange, disabled }) {
|
|
|
8890
9689
|
children: "null"
|
|
8891
9690
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
8892
9691
|
className: "hint",
|
|
8893
|
-
children: "
|
|
9692
|
+
children: t("schema.fixedValue")
|
|
8894
9693
|
})]
|
|
8895
9694
|
});
|
|
8896
9695
|
default: return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
@@ -8903,11 +9702,12 @@ function ScalarInput({ schema, value, onChange, disabled }) {
|
|
|
8903
9702
|
}
|
|
8904
9703
|
}
|
|
8905
9704
|
function UnionField({ options, value, onChange, depth, disabled }) {
|
|
9705
|
+
const t = useT();
|
|
8906
9706
|
const [selected, setSelected] = (0, import_react.useState)(0);
|
|
8907
9707
|
const active = options[selected];
|
|
8908
9708
|
if (!active) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8909
9709
|
className: "hint",
|
|
8910
|
-
children: "
|
|
9710
|
+
children: t("schema.unionNoBranch")
|
|
8911
9711
|
});
|
|
8912
9712
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
8913
9713
|
style: { paddingLeft: depth * 14 },
|
|
@@ -8926,9 +9726,8 @@ function UnionField({ options, value, onChange, depth, disabled }) {
|
|
|
8926
9726
|
children: options.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", {
|
|
8927
9727
|
value: i,
|
|
8928
9728
|
children: [
|
|
8929
|
-
"
|
|
8930
|
-
|
|
8931
|
-
"] — ",
|
|
9729
|
+
t("schema.optionIndex", { index: i }),
|
|
9730
|
+
" — ",
|
|
8932
9731
|
opt.kind
|
|
8933
9732
|
]
|
|
8934
9733
|
}, i))
|
|
@@ -8944,12 +9743,13 @@ function UnionField({ options, value, onChange, depth, disabled }) {
|
|
|
8944
9743
|
});
|
|
8945
9744
|
}
|
|
8946
9745
|
function ContainerChildren({ schema, value, onChange, depth, disabled }) {
|
|
9746
|
+
const t = useT();
|
|
8947
9747
|
const c = schema.children ?? {};
|
|
8948
9748
|
if (schema.kind === "array") {
|
|
8949
9749
|
const itemSchema = isSchema$1(c.items) ? c.items : void 0;
|
|
8950
9750
|
if (!itemSchema) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
8951
9751
|
className: "hint",
|
|
8952
|
-
children: "
|
|
9752
|
+
children: t("schema.arrayNoItem")
|
|
8953
9753
|
});
|
|
8954
9754
|
const arr = Array.isArray(value) ? value : [];
|
|
8955
9755
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [arr.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -8971,14 +9771,14 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
|
|
|
8971
9771
|
className: "tiny",
|
|
8972
9772
|
disabled,
|
|
8973
9773
|
onClick: () => onChange(arr.filter((_, j) => j !== i)),
|
|
8974
|
-
children: "
|
|
9774
|
+
children: t("common.delete")
|
|
8975
9775
|
})]
|
|
8976
9776
|
}, i)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
8977
9777
|
type: "button",
|
|
8978
9778
|
className: "tiny",
|
|
8979
9779
|
disabled,
|
|
8980
9780
|
onClick: () => onChange([...arr, sampleFromSchema(itemSchema)]),
|
|
8981
|
-
children: "
|
|
9781
|
+
children: t("schema.addItem")
|
|
8982
9782
|
})] });
|
|
8983
9783
|
}
|
|
8984
9784
|
if (schema.kind === "tuple") {
|
|
@@ -9024,14 +9824,14 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
|
|
|
9024
9824
|
paddingLeft: depth * 14,
|
|
9025
9825
|
margin: "4px 0"
|
|
9026
9826
|
},
|
|
9027
|
-
children: "
|
|
9827
|
+
children: t("schema.strictHint")
|
|
9028
9828
|
})] });
|
|
9029
9829
|
}
|
|
9030
9830
|
if (schema.kind === "record") {
|
|
9031
9831
|
const valueSchema = isSchema$1(c.values) ? c.values : void 0;
|
|
9032
9832
|
if (!valueSchema) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
9033
9833
|
className: "hint",
|
|
9034
|
-
children: "
|
|
9834
|
+
children: t("schema.recordNoValue")
|
|
9035
9835
|
});
|
|
9036
9836
|
const obj = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
9037
9837
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [Object.entries(obj).map(([key, v]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -9056,7 +9856,7 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
|
|
|
9056
9856
|
delete next[key];
|
|
9057
9857
|
onChange(next);
|
|
9058
9858
|
},
|
|
9059
|
-
children: "
|
|
9859
|
+
children: t("common.delete")
|
|
9060
9860
|
})]
|
|
9061
9861
|
}, key)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AddRecordKey, {
|
|
9062
9862
|
onAdd: (key, v) => onChange({
|
|
@@ -9070,12 +9870,13 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
|
|
|
9070
9870
|
return null;
|
|
9071
9871
|
}
|
|
9072
9872
|
function AddRecordKey({ onAdd, sample, disabled }) {
|
|
9873
|
+
const t = useT();
|
|
9073
9874
|
const [key, setKey] = (0, import_react.useState)("");
|
|
9074
9875
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
9075
9876
|
className: "sf-record-add",
|
|
9076
9877
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
9077
9878
|
className: "sf-input",
|
|
9078
|
-
placeholder: "
|
|
9879
|
+
placeholder: t("schema.recordAddPlaceholder"),
|
|
9079
9880
|
value: key,
|
|
9080
9881
|
onChange: (e) => setKey(e.target.value),
|
|
9081
9882
|
disabled
|
|
@@ -9087,11 +9888,12 @@ function AddRecordKey({ onAdd, sample, disabled }) {
|
|
|
9087
9888
|
onAdd(key, sample());
|
|
9088
9889
|
setKey("");
|
|
9089
9890
|
},
|
|
9090
|
-
children: "
|
|
9891
|
+
children: t("schema.addRecordKey")
|
|
9091
9892
|
})]
|
|
9092
9893
|
});
|
|
9093
9894
|
}
|
|
9094
9895
|
function UnknownLeaf({ schema, value, onChange, label, depth, disabled }) {
|
|
9896
|
+
const t = useT();
|
|
9095
9897
|
const [text, setText] = (0, import_react.useState)(() => JSON.stringify(value ?? null, null, 2));
|
|
9096
9898
|
const [error, setError] = (0, import_react.useState)(null);
|
|
9097
9899
|
const commit = (next) => {
|
|
@@ -9133,9 +9935,9 @@ function UnknownLeaf({ schema, value, onChange, label, depth, disabled }) {
|
|
|
9133
9935
|
value: text,
|
|
9134
9936
|
disabled,
|
|
9135
9937
|
onChange: (e) => commit(e.target.value)
|
|
9136
|
-
}), error && /* @__PURE__ */ (0, import_jsx_runtime.
|
|
9938
|
+
}), error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
9137
9939
|
className: "error small",
|
|
9138
|
-
children:
|
|
9940
|
+
children: t("test.jsonError", { error })
|
|
9139
9941
|
})]
|
|
9140
9942
|
})]
|
|
9141
9943
|
});
|
|
@@ -9149,19 +9951,27 @@ function Constraints({ schema }) {
|
|
|
9149
9951
|
}
|
|
9150
9952
|
//#endregion
|
|
9151
9953
|
//#region webui/src/components/TestPanel.tsx
|
|
9152
|
-
var COPY_OPTIONS = [{
|
|
9153
|
-
value: "curl",
|
|
9154
|
-
label: "复制 curl"
|
|
9155
|
-
}, {
|
|
9156
|
-
value: "fetch",
|
|
9157
|
-
label: "复制 fetch"
|
|
9158
|
-
}];
|
|
9159
9954
|
/** 格式化耗时:<1s 用 ms,否则用 s */
|
|
9160
9955
|
function formatElapsed(ms) {
|
|
9161
9956
|
if (ms < 1e3) return `${ms.toFixed(0)} ms`;
|
|
9162
9957
|
return `${(ms / 1e3).toFixed(2)} s`;
|
|
9163
9958
|
}
|
|
9164
9959
|
function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
9960
|
+
const t = useT();
|
|
9961
|
+
const COPY_OPTIONS = [
|
|
9962
|
+
{
|
|
9963
|
+
value: "curl",
|
|
9964
|
+
label: t("test.copyCurl")
|
|
9965
|
+
},
|
|
9966
|
+
{
|
|
9967
|
+
value: "curl-cmd",
|
|
9968
|
+
label: t("test.copyCurlCmd")
|
|
9969
|
+
},
|
|
9970
|
+
{
|
|
9971
|
+
value: "fetch",
|
|
9972
|
+
label: t("test.copyFetch")
|
|
9973
|
+
}
|
|
9974
|
+
];
|
|
9165
9975
|
const paramSchemas = (0, import_react.useMemo)(() => detail.signature.slice(1), [detail.signature]);
|
|
9166
9976
|
const isStreamReturn = detail.signature[0]?.kind === "stream";
|
|
9167
9977
|
const [values, setValues] = (0, import_react.useState)([]);
|
|
@@ -9219,8 +10029,11 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9219
10029
|
setOutput(lines.join("\n"));
|
|
9220
10030
|
}
|
|
9221
10031
|
const totalAt = performance.now() - startedAt;
|
|
9222
|
-
if (idx === 0) lines.push(
|
|
9223
|
-
else lines.push(
|
|
10032
|
+
if (idx === 0) lines.push(t("test.streamEndedEmpty", { duration: formatElapsed(totalAt) }));
|
|
10033
|
+
else lines.push(t("test.streamEnded", {
|
|
10034
|
+
count: idx,
|
|
10035
|
+
duration: formatElapsed(totalAt)
|
|
10036
|
+
}));
|
|
9224
10037
|
setOutput(lines.join("\n"));
|
|
9225
10038
|
setElapsed({
|
|
9226
10039
|
total: totalAt,
|
|
@@ -9252,7 +10065,7 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9252
10065
|
id: 1
|
|
9253
10066
|
};
|
|
9254
10067
|
const url = absoluteEndpoint(endpoint);
|
|
9255
|
-
code = kind === "curl" ? buildCurl(url, body) : buildFetch(url, body);
|
|
10068
|
+
code = kind === "curl" ? buildCurl(url, body) : kind === "curl-cmd" ? buildCurlCmd(url, body) : buildFetch(url, body);
|
|
9256
10069
|
} catch (e) {
|
|
9257
10070
|
setCopyError(e instanceof Error ? e.message : String(e));
|
|
9258
10071
|
return;
|
|
@@ -9262,24 +10075,20 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9262
10075
|
setCopied(true);
|
|
9263
10076
|
setTimeout(() => setCopied(false), 2e3);
|
|
9264
10077
|
} catch (e) {
|
|
9265
|
-
setCopyError(
|
|
10078
|
+
setCopyError(t("common.copyFailed", { error: e instanceof Error ? e.message : String(e) }));
|
|
9266
10079
|
}
|
|
9267
10080
|
};
|
|
9268
10081
|
const canCopy = transport === "http";
|
|
9269
|
-
const currentLabel = COPY_OPTIONS.find((o) => o.value === copyKind)?.label ?? "
|
|
10082
|
+
const currentLabel = COPY_OPTIONS.find((o) => o.value === copyKind)?.label ?? t("common.copy");
|
|
9270
10083
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
9271
10084
|
className: "test",
|
|
9272
10085
|
children: [
|
|
9273
10086
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
|
|
9274
|
-
"
|
|
10087
|
+
t("test.params"),
|
|
9275
10088
|
" ",
|
|
9276
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
10089
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
9277
10090
|
className: "hint",
|
|
9278
|
-
children:
|
|
9279
|
-
"(",
|
|
9280
|
-
paramSchemas.length,
|
|
9281
|
-
" 个,按签名自动生成)"
|
|
9282
|
-
]
|
|
10091
|
+
children: t("test.paramsHint", { count: paramSchemas.length })
|
|
9283
10092
|
})
|
|
9284
10093
|
] }),
|
|
9285
10094
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaForm, {
|
|
@@ -9294,7 +10103,7 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9294
10103
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
9295
10104
|
onClick: execute,
|
|
9296
10105
|
disabled: !method || running,
|
|
9297
|
-
children: running ? isStreamReturn ? "
|
|
10106
|
+
children: running ? isStreamReturn ? t("test.receiving") : t("test.executing") : isStreamReturn ? t("test.executeStream") : t("test.execute")
|
|
9298
10107
|
}),
|
|
9299
10108
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
9300
10109
|
className: "split-button",
|
|
@@ -9305,8 +10114,8 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9305
10114
|
className: "split-button-main",
|
|
9306
10115
|
onClick: () => void copyAs(copyKind),
|
|
9307
10116
|
disabled: !method || !canCopy,
|
|
9308
|
-
title: canCopy ? "
|
|
9309
|
-
children: copied ? "
|
|
10117
|
+
title: canCopy ? t("test.copyTitle") : t("test.copyDisabledTitle"),
|
|
10118
|
+
children: copied ? t("common.copied") : currentLabel
|
|
9310
10119
|
}),
|
|
9311
10120
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
9312
10121
|
type: "button",
|
|
@@ -9315,7 +10124,7 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9315
10124
|
disabled: !method || !canCopy,
|
|
9316
10125
|
"aria-haspopup": "menu",
|
|
9317
10126
|
"aria-expanded": menuOpen,
|
|
9318
|
-
title: "
|
|
10127
|
+
title: t("test.chooseFormat"),
|
|
9319
10128
|
children: "▾"
|
|
9320
10129
|
}),
|
|
9321
10130
|
menuOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", {
|
|
@@ -9343,7 +10152,7 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9343
10152
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
9344
10153
|
onClick: () => setValues(paramSchemas.map(sampleFromSchema)),
|
|
9345
10154
|
disabled: !method,
|
|
9346
|
-
children: "
|
|
10155
|
+
children: t("test.resetToSample")
|
|
9347
10156
|
}),
|
|
9348
10157
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
9349
10158
|
onClick: () => {
|
|
@@ -9351,15 +10160,15 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9351
10160
|
setElapsed(null);
|
|
9352
10161
|
},
|
|
9353
10162
|
disabled: !output && !elapsed,
|
|
9354
|
-
children: "
|
|
10163
|
+
children: t("test.clearOutput")
|
|
9355
10164
|
})
|
|
9356
10165
|
]
|
|
9357
10166
|
}),
|
|
9358
10167
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
|
|
9359
|
-
"
|
|
10168
|
+
t("test.result"),
|
|
9360
10169
|
isStreamReturn && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
9361
10170
|
className: "hint",
|
|
9362
|
-
children: "
|
|
10171
|
+
children: t("test.resultStream")
|
|
9363
10172
|
}),
|
|
9364
10173
|
elapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
9365
10174
|
className: "elapsed-badge",
|
|
@@ -9371,7 +10180,9 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9371
10180
|
className: "hint",
|
|
9372
10181
|
children: [
|
|
9373
10182
|
" ",
|
|
9374
|
-
"·
|
|
10183
|
+
"· ",
|
|
10184
|
+
t("test.firstFrame"),
|
|
10185
|
+
" ",
|
|
9375
10186
|
formatElapsed(elapsed.firstFrame)
|
|
9376
10187
|
]
|
|
9377
10188
|
})
|
|
@@ -9381,11 +10192,12 @@ function TestPanel({ method, detail, rpc, transport, endpoint }) {
|
|
|
9381
10192
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", {
|
|
9382
10193
|
className: "output",
|
|
9383
10194
|
ref: outRef,
|
|
9384
|
-
children: output || "
|
|
10195
|
+
children: output || t("test.notExecuted")
|
|
9385
10196
|
})
|
|
9386
10197
|
]
|
|
9387
10198
|
});
|
|
9388
10199
|
}
|
|
10200
|
+
/** bash / POSIX sh:单引号包裹,内部单引号用 '\'' 转义;反斜杠续行。 */
|
|
9389
10201
|
function buildCurl(url, body) {
|
|
9390
10202
|
const quotedBody = `'${JSON.stringify(body, null, 2).replace(/'/g, `'\\''`)}'`;
|
|
9391
10203
|
return [
|
|
@@ -9394,6 +10206,23 @@ function buildCurl(url, body) {
|
|
|
9394
10206
|
` -d ${quotedBody}`
|
|
9395
10207
|
].join(" \\\n");
|
|
9396
10208
|
}
|
|
10209
|
+
/**
|
|
10210
|
+
* Windows CMD:双引号包裹。
|
|
10211
|
+
* - 双引号 " 用 \" 转义(curl.exe 在 cmd 下按 C 运行时规则解析)
|
|
10212
|
+
* - % 用 %% 转义(避免被 cmd 当作变量展开)
|
|
10213
|
+
* - 换行用 ^ 续行
|
|
10214
|
+
* - 其余字符原样保留
|
|
10215
|
+
*/
|
|
10216
|
+
function buildCurlCmd(url, body) {
|
|
10217
|
+
const bodyText = JSON.stringify(body);
|
|
10218
|
+
const escapeCmdDoubleQuoted = (s) => s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/%/g, "%%");
|
|
10219
|
+
const quotedBody = `"${escapeCmdDoubleQuoted(bodyText)}"`;
|
|
10220
|
+
return [
|
|
10221
|
+
`curl -X POST ${`"${escapeCmdDoubleQuoted(url)}"`} ^`,
|
|
10222
|
+
` -H "Content-Type: application/json" ^`,
|
|
10223
|
+
` -d ${quotedBody}`
|
|
10224
|
+
].join("\n");
|
|
10225
|
+
}
|
|
9397
10226
|
function buildFetch(url, body) {
|
|
9398
10227
|
const indented = JSON.stringify(body, null, 2).split("\n").map((line, i) => i === 0 ? line : " " + line).join("\n");
|
|
9399
10228
|
return [
|
|
@@ -9445,6 +10274,7 @@ function rateClass(v) {
|
|
|
9445
10274
|
return "rate-cold";
|
|
9446
10275
|
}
|
|
9447
10276
|
function MetricsPanel({ snapshot, previous, fetchedAt, loading, error, available, onRefresh, autoRefresh, onAutoRefreshChange, intervalMs, onIntervalChange }) {
|
|
10277
|
+
const t = useT();
|
|
9448
10278
|
const derived = (0, import_react.useMemo)(() => {
|
|
9449
10279
|
if (!snapshot) return [];
|
|
9450
10280
|
const dtSeconds = previous && fetchedAt ? (fetchedAt - previous.fetchedAt) / 1e3 : void 0;
|
|
@@ -9486,15 +10316,9 @@ function MetricsPanel({ snapshot, previous, fetchedAt, loading, error, available
|
|
|
9486
10316
|
}, [snapshot]);
|
|
9487
10317
|
if (!available) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
9488
10318
|
className: "metrics",
|
|
9489
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "
|
|
10319
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: t("metrics.title") }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
9490
10320
|
className: "hint",
|
|
9491
|
-
children:
|
|
9492
|
-
"服务端未启用 ",
|
|
9493
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "system.metrics" }),
|
|
9494
|
-
"(",
|
|
9495
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "withSystemMethods: false" }),
|
|
9496
|
-
" 或未注册)。"
|
|
9497
|
-
]
|
|
10321
|
+
children: t("metrics.unavailable")
|
|
9498
10322
|
})]
|
|
9499
10323
|
});
|
|
9500
10324
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
@@ -9502,7 +10326,7 @@ function MetricsPanel({ snapshot, previous, fetchedAt, loading, error, available
|
|
|
9502
10326
|
children: [
|
|
9503
10327
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
|
|
9504
10328
|
className: "metrics-header",
|
|
9505
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "
|
|
10329
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: t("metrics.title") }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
9506
10330
|
className: "metrics-controls",
|
|
9507
10331
|
children: [
|
|
9508
10332
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
@@ -9511,14 +10335,14 @@ function MetricsPanel({ snapshot, previous, fetchedAt, loading, error, available
|
|
|
9511
10335
|
type: "checkbox",
|
|
9512
10336
|
checked: autoRefresh,
|
|
9513
10337
|
onChange: (e) => onAutoRefreshChange(e.target.checked)
|
|
9514
|
-
}), "
|
|
10338
|
+
}), t("metrics.autoRefresh")]
|
|
9515
10339
|
}),
|
|
9516
10340
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", {
|
|
9517
10341
|
className: "sf-input",
|
|
9518
10342
|
value: intervalMs,
|
|
9519
10343
|
onChange: (e) => onIntervalChange(Number(e.target.value)),
|
|
9520
10344
|
disabled: !autoRefresh,
|
|
9521
|
-
title: "
|
|
10345
|
+
title: t("metrics.interval"),
|
|
9522
10346
|
children: [
|
|
9523
10347
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", {
|
|
9524
10348
|
value: 1e3,
|
|
@@ -9541,11 +10365,15 @@ function MetricsPanel({ snapshot, previous, fetchedAt, loading, error, available
|
|
|
9541
10365
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
9542
10366
|
onClick: onRefresh,
|
|
9543
10367
|
disabled: loading,
|
|
9544
|
-
children: loading ? "
|
|
10368
|
+
children: loading ? t("metrics.refreshing") : t("metrics.refreshNow")
|
|
9545
10369
|
}),
|
|
9546
10370
|
snapshot && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
9547
10371
|
className: "hint",
|
|
9548
|
-
children: [
|
|
10372
|
+
children: [
|
|
10373
|
+
t("metrics.uptime"),
|
|
10374
|
+
" ",
|
|
10375
|
+
formatDuration(snapshot.uptimeMs / 1e3)
|
|
10376
|
+
]
|
|
9549
10377
|
})
|
|
9550
10378
|
]
|
|
9551
10379
|
})]
|
|
@@ -9556,64 +10384,56 @@ function MetricsPanel({ snapshot, previous, fetchedAt, loading, error, available
|
|
|
9556
10384
|
}),
|
|
9557
10385
|
!snapshot && !error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
9558
10386
|
className: "hint",
|
|
9559
|
-
children: "
|
|
10387
|
+
children: t("metrics.loading")
|
|
9560
10388
|
}),
|
|
9561
10389
|
snapshot && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
9562
10390
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
9563
10391
|
className: "metrics-cards",
|
|
9564
10392
|
children: [
|
|
9565
10393
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
|
|
9566
|
-
label: "
|
|
10394
|
+
label: t("metrics.methods"),
|
|
9567
10395
|
value: String(totals.methods)
|
|
9568
10396
|
}),
|
|
9569
10397
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
|
|
9570
|
-
label: "
|
|
10398
|
+
label: t("metrics.calls"),
|
|
9571
10399
|
value: String(totals.calls)
|
|
9572
10400
|
}),
|
|
9573
10401
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
|
|
9574
|
-
label: "
|
|
10402
|
+
label: t("metrics.streams"),
|
|
9575
10403
|
value: String(totals.streams)
|
|
9576
10404
|
}),
|
|
9577
10405
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
|
|
9578
|
-
label: "
|
|
10406
|
+
label: t("metrics.errors"),
|
|
9579
10407
|
value: String(totals.errors),
|
|
9580
10408
|
tone: totals.errors > 0 ? "danger" : void 0
|
|
9581
10409
|
}),
|
|
9582
10410
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
|
|
9583
|
-
label: "
|
|
10411
|
+
label: t("metrics.errorRate"),
|
|
9584
10412
|
value: totals.calls > 0 ? formatPercent(totals.errors / totals.calls) : "—",
|
|
9585
10413
|
tone: totals.calls > 0 && totals.errors / totals.calls > .05 ? "danger" : void 0
|
|
9586
10414
|
}),
|
|
9587
10415
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricCard, {
|
|
9588
|
-
label: "
|
|
10416
|
+
label: t("metrics.invalidRequests"),
|
|
9589
10417
|
value: String(snapshot.invalidRequests),
|
|
9590
10418
|
tone: snapshot.invalidRequests > 0 ? "warn" : void 0
|
|
9591
10419
|
})
|
|
9592
10420
|
]
|
|
9593
10421
|
}),
|
|
9594
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: ["
|
|
10422
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [t("metrics.nonStreamTitle"), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
9595
10423
|
className: "hint",
|
|
9596
|
-
children: [
|
|
9597
|
-
" (",
|
|
9598
|
-
nonStreamMethods.length,
|
|
9599
|
-
")"
|
|
9600
|
-
]
|
|
10424
|
+
children: [" ", t("metrics.countHint", { count: nonStreamMethods.length })]
|
|
9601
10425
|
})] }),
|
|
9602
10426
|
nonStreamMethods.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
9603
10427
|
className: "hint",
|
|
9604
|
-
children: "
|
|
10428
|
+
children: t("metrics.noData")
|
|
9605
10429
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NonStreamTable, { rows: nonStreamMethods }),
|
|
9606
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: ["
|
|
10430
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [t("metrics.streamTitle"), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
9607
10431
|
className: "hint",
|
|
9608
|
-
children: [
|
|
9609
|
-
" (",
|
|
9610
|
-
streamMethods.length,
|
|
9611
|
-
")"
|
|
9612
|
-
]
|
|
10432
|
+
children: [" ", t("metrics.countHint", { count: streamMethods.length })]
|
|
9613
10433
|
})] }),
|
|
9614
10434
|
streamMethods.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
9615
10435
|
className: "hint",
|
|
9616
|
-
children: "
|
|
10436
|
+
children: t("metrics.noStreams")
|
|
9617
10437
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StreamTable, { rows: streamMethods })
|
|
9618
10438
|
] })
|
|
9619
10439
|
]
|
|
@@ -9632,41 +10452,42 @@ function MetricCard({ label, value, tone }) {
|
|
|
9632
10452
|
});
|
|
9633
10453
|
}
|
|
9634
10454
|
function NonStreamTable({ rows }) {
|
|
10455
|
+
const t = useT();
|
|
9635
10456
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
|
|
9636
10457
|
className: "metrics-table",
|
|
9637
10458
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
9638
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "
|
|
10459
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: t("metrics.colMethod") }),
|
|
9639
10460
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9640
10461
|
className: "num",
|
|
9641
|
-
children: "
|
|
10462
|
+
children: t("metrics.colCalls")
|
|
9642
10463
|
}),
|
|
9643
10464
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9644
10465
|
className: "num",
|
|
9645
|
-
children: "
|
|
10466
|
+
children: t("metrics.colRate")
|
|
9646
10467
|
}),
|
|
9647
10468
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9648
10469
|
className: "num",
|
|
9649
|
-
children: "
|
|
10470
|
+
children: t("metrics.colErrors")
|
|
9650
10471
|
}),
|
|
9651
10472
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9652
10473
|
className: "num",
|
|
9653
|
-
children: "
|
|
10474
|
+
children: t("metrics.colErrPct")
|
|
9654
10475
|
}),
|
|
9655
10476
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9656
10477
|
className: "num",
|
|
9657
|
-
children: "
|
|
10478
|
+
children: t("metrics.colP50")
|
|
9658
10479
|
}),
|
|
9659
10480
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9660
10481
|
className: "num",
|
|
9661
|
-
children: "
|
|
10482
|
+
children: t("metrics.colP95")
|
|
9662
10483
|
}),
|
|
9663
10484
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9664
10485
|
className: "num",
|
|
9665
|
-
children: "
|
|
10486
|
+
children: t("metrics.colP99")
|
|
9666
10487
|
}),
|
|
9667
10488
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9668
10489
|
className: "num",
|
|
9669
|
-
children: "
|
|
10490
|
+
children: t("metrics.colAvg")
|
|
9670
10491
|
})
|
|
9671
10492
|
] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: rows.map((r) => {
|
|
9672
10493
|
const errorCount = Object.values(r.stats.errorsByCode).reduce((a, b) => a + b, 0);
|
|
@@ -9714,49 +10535,50 @@ function NonStreamTable({ rows }) {
|
|
|
9714
10535
|
});
|
|
9715
10536
|
}
|
|
9716
10537
|
function StreamTable({ rows }) {
|
|
10538
|
+
const t = useT();
|
|
9717
10539
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", {
|
|
9718
10540
|
className: "metrics-table",
|
|
9719
10541
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
9720
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "
|
|
10542
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: t("metrics.colMethod") }),
|
|
9721
10543
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9722
10544
|
className: "num",
|
|
9723
|
-
children: "
|
|
10545
|
+
children: t("metrics.colOpened")
|
|
9724
10546
|
}),
|
|
9725
10547
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9726
10548
|
className: "num",
|
|
9727
|
-
children: "
|
|
10549
|
+
children: t("metrics.colCompleted")
|
|
9728
10550
|
}),
|
|
9729
10551
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9730
10552
|
className: "num",
|
|
9731
|
-
children: "
|
|
10553
|
+
children: t("metrics.colFailed")
|
|
9732
10554
|
}),
|
|
9733
10555
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9734
10556
|
className: "num",
|
|
9735
|
-
children: "
|
|
10557
|
+
children: t("metrics.colAborted")
|
|
9736
10558
|
}),
|
|
9737
10559
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9738
10560
|
className: "num",
|
|
9739
|
-
children: "
|
|
10561
|
+
children: t("metrics.colCompletePct")
|
|
9740
10562
|
}),
|
|
9741
10563
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9742
10564
|
className: "num",
|
|
9743
|
-
children: "
|
|
10565
|
+
children: t("metrics.colAbortPct")
|
|
9744
10566
|
}),
|
|
9745
10567
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9746
10568
|
className: "num",
|
|
9747
|
-
children: "
|
|
10569
|
+
children: t("metrics.colAvgChunks")
|
|
9748
10570
|
}),
|
|
9749
10571
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9750
10572
|
className: "num",
|
|
9751
|
-
children: "
|
|
10573
|
+
children: t("metrics.colTtfbP50")
|
|
9752
10574
|
}),
|
|
9753
10575
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9754
10576
|
className: "num",
|
|
9755
|
-
children: "
|
|
10577
|
+
children: t("metrics.colTtfbP95")
|
|
9756
10578
|
}),
|
|
9757
10579
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", {
|
|
9758
10580
|
className: "num",
|
|
9759
|
-
children: "
|
|
10581
|
+
children: t("metrics.colDurationAvg")
|
|
9760
10582
|
})
|
|
9761
10583
|
] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: rows.map((r) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
9762
10584
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", {
|
|
@@ -9808,58 +10630,88 @@ function StreamTable({ rows }) {
|
|
|
9808
10630
|
});
|
|
9809
10631
|
}
|
|
9810
10632
|
//#endregion
|
|
9811
|
-
//#region webui/src/
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
10633
|
+
//#region webui/src/components/Footer.tsx
|
|
10634
|
+
var NPM_URL = "https://www.npmjs.com/package/@yuhere/js-jsonrpc2/";
|
|
10635
|
+
var GITHUB_URL = "https://github.com/yuhere/js-jsonrpc2";
|
|
10636
|
+
function Footer() {
|
|
10637
|
+
const t = useT();
|
|
10638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("footer", {
|
|
10639
|
+
className: "footer",
|
|
10640
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
10641
|
+
className: "footer-version",
|
|
10642
|
+
title: t("footer.version"),
|
|
10643
|
+
children: ["v", "2.1.13"]
|
|
10644
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10645
|
+
className: "footer-links",
|
|
10646
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
10647
|
+
className: "npm-link",
|
|
10648
|
+
href: NPM_URL,
|
|
10649
|
+
target: "_blank",
|
|
10650
|
+
rel: "noopener noreferrer",
|
|
10651
|
+
title: t("footer.npm"),
|
|
10652
|
+
"aria-label": t("footer.npm"),
|
|
10653
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
|
|
10654
|
+
viewBox: "0 0 18 7",
|
|
10655
|
+
width: "36",
|
|
10656
|
+
height: "14",
|
|
10657
|
+
role: "img",
|
|
10658
|
+
"aria-hidden": "true",
|
|
10659
|
+
focusable: "false",
|
|
10660
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
|
|
10661
|
+
fill: "#CB3837",
|
|
10662
|
+
d: "M0 0h18v7H9v-1.5H7.5V7H0z"
|
|
10663
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
|
|
10664
|
+
fill: "#fff",
|
|
10665
|
+
d: "M1.5 1.5h3v4h-1v-3h-1v3h-1zm4 0h3v4h-1v-3h-1v3h-1zm4 0h4v4h-1v-3h-1v3h-1v-3h-1z"
|
|
10666
|
+
})]
|
|
10667
|
+
})
|
|
10668
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
10669
|
+
className: "github-link",
|
|
10670
|
+
href: GITHUB_URL,
|
|
10671
|
+
target: "_blank",
|
|
10672
|
+
rel: "noopener noreferrer",
|
|
10673
|
+
title: t("footer.github"),
|
|
10674
|
+
"aria-label": t("footer.github"),
|
|
10675
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
|
|
10676
|
+
viewBox: "0 0 16 16",
|
|
10677
|
+
width: "16",
|
|
10678
|
+
height: "16",
|
|
10679
|
+
role: "img",
|
|
10680
|
+
"aria-hidden": "true",
|
|
10681
|
+
focusable: "false",
|
|
10682
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
|
|
10683
|
+
fill: "currentColor",
|
|
10684
|
+
d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"
|
|
10685
|
+
})
|
|
10686
|
+
})
|
|
10687
|
+
})]
|
|
10688
|
+
})]
|
|
10689
|
+
});
|
|
9825
10690
|
}
|
|
9826
|
-
|
|
10691
|
+
//#endregion
|
|
10692
|
+
//#region webui/src/utils/fuzzy.ts
|
|
10693
|
+
function compileFuzzyQuery(input) {
|
|
9827
10694
|
const raw = input ?? "";
|
|
9828
|
-
const
|
|
9829
|
-
if (trimmed.length === 0) return {
|
|
9830
|
-
includes: [],
|
|
9831
|
-
excludes: [],
|
|
9832
|
-
raw,
|
|
9833
|
-
passthrough: true
|
|
9834
|
-
};
|
|
9835
|
-
const includes = [];
|
|
9836
|
-
const excludes = [];
|
|
9837
|
-
for (const part of trimmed.split(",")) {
|
|
9838
|
-
const pat = part.trim();
|
|
9839
|
-
if (pat.length === 0) continue;
|
|
9840
|
-
if (pat.startsWith("!")) {
|
|
9841
|
-
const body = pat.slice(1).trim();
|
|
9842
|
-
if (body.length > 0) excludes.push(globToRegExp(body));
|
|
9843
|
-
} else includes.push(globToRegExp(pat));
|
|
9844
|
-
}
|
|
10695
|
+
const terms = raw.trim().toLowerCase().split(/\s+/).filter((t) => t.length > 0);
|
|
9845
10696
|
return {
|
|
9846
|
-
|
|
9847
|
-
excludes,
|
|
10697
|
+
terms,
|
|
9848
10698
|
raw,
|
|
9849
|
-
passthrough:
|
|
10699
|
+
passthrough: terms.length === 0
|
|
9850
10700
|
};
|
|
9851
10701
|
}
|
|
9852
|
-
function
|
|
9853
|
-
if (
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
10702
|
+
function matchFuzzy(query, method) {
|
|
10703
|
+
if (query.passthrough) return true;
|
|
10704
|
+
const target = method.toLowerCase();
|
|
10705
|
+
return query.terms.every((t) => target.includes(t));
|
|
10706
|
+
}
|
|
10707
|
+
function filterFuzzyMethods(query, methods) {
|
|
10708
|
+
if (query.passthrough) return methods;
|
|
10709
|
+
return methods.filter((m) => matchFuzzy(query, m));
|
|
9857
10710
|
}
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
if (filter.passthrough) return methods;
|
|
10711
|
+
function filterFuzzySnapshotMethods(query, methods) {
|
|
10712
|
+
if (query.passthrough) return methods;
|
|
9861
10713
|
const out = {};
|
|
9862
|
-
for (const [method, stats] of Object.entries(methods)) if (
|
|
10714
|
+
for (const [method, stats] of Object.entries(methods)) if (matchFuzzy(query, method)) out[method] = stats;
|
|
9863
10715
|
return out;
|
|
9864
10716
|
}
|
|
9865
10717
|
//#endregion
|
|
@@ -9996,12 +10848,16 @@ function downloadText(filename, text, mime = "text/plain") {
|
|
|
9996
10848
|
//#region webui/src/App.tsx
|
|
9997
10849
|
var ENDPOINT = "";
|
|
9998
10850
|
function App() {
|
|
10851
|
+
const { t } = useI18n();
|
|
9999
10852
|
const [transport, setTransport] = (0, import_react.useState)("http");
|
|
10000
10853
|
const [selected, setSelected] = (0, import_react.useState)("");
|
|
10001
10854
|
const [generatingDocs, setGeneratingDocs] = (0, import_react.useState)(false);
|
|
10002
10855
|
const [view, setView] = (0, import_react.useState)("methods");
|
|
10003
|
-
const [
|
|
10004
|
-
const
|
|
10856
|
+
const [methodSearch, setMethodSearch] = (0, import_react.useState)("");
|
|
10857
|
+
const [metricsSearch, setMetricsSearch] = (0, import_react.useState)("");
|
|
10858
|
+
const debouncedMethodSearch = useDebouncedValue(methodSearch, 250);
|
|
10859
|
+
const debouncedMetricsSearch = useDebouncedValue(metricsSearch, 250);
|
|
10860
|
+
const rpc = (0, import_react.useMemo)(() => createRPC({
|
|
10005
10861
|
transport,
|
|
10006
10862
|
endpoint: ENDPOINT
|
|
10007
10863
|
}), [transport]);
|
|
@@ -10009,18 +10865,20 @@ function App() {
|
|
|
10009
10865
|
const { methods, loading, error, refresh } = useMethods(rpc);
|
|
10010
10866
|
const detail = useMethodDetail(rpc, selected);
|
|
10011
10867
|
const metrics = useMetrics(rpc, view === "metrics");
|
|
10012
|
-
const
|
|
10013
|
-
const
|
|
10868
|
+
const methodQuery = (0, import_react.useMemo)(() => compileFuzzyQuery(debouncedMethodSearch), [debouncedMethodSearch]);
|
|
10869
|
+
const metricsQuery = (0, import_react.useMemo)(() => compileFuzzyQuery(debouncedMetricsSearch), [debouncedMetricsSearch]);
|
|
10870
|
+
const filteredMethods = (0, import_react.useMemo)(() => filterFuzzyMethods(methodQuery, methods), [methodQuery, methods]);
|
|
10871
|
+
const filteredMetrics = (0, import_react.useMemo)(() => {
|
|
10014
10872
|
if (!metrics.snapshot) return void 0;
|
|
10015
|
-
if (
|
|
10873
|
+
if (metricsQuery.passthrough) return metrics.snapshot;
|
|
10016
10874
|
return {
|
|
10017
10875
|
...metrics.snapshot,
|
|
10018
|
-
methods:
|
|
10876
|
+
methods: filterFuzzySnapshotMethods(metricsQuery, metrics.snapshot.methods)
|
|
10019
10877
|
};
|
|
10020
|
-
}, [metrics.snapshot,
|
|
10878
|
+
}, [metrics.snapshot, metricsQuery]);
|
|
10021
10879
|
const generateDocs = (0, import_react.useCallback)(async () => {
|
|
10022
10880
|
if (methods.length === 0) {
|
|
10023
|
-
alert("
|
|
10881
|
+
alert(t("alerts.emptyMethods"));
|
|
10024
10882
|
return;
|
|
10025
10883
|
}
|
|
10026
10884
|
setGeneratingDocs(true);
|
|
@@ -10028,131 +10886,137 @@ function App() {
|
|
|
10028
10886
|
const md = renderMarkdown(await collectApiDoc(rpc, methods));
|
|
10029
10887
|
downloadText(`jsonrpc-api-doc-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.md`, md, "text/markdown");
|
|
10030
10888
|
} catch (e) {
|
|
10031
|
-
alert(
|
|
10889
|
+
alert(t("alerts.docsFailed", { error: e instanceof Error ? e.message : String(e) }));
|
|
10032
10890
|
} finally {
|
|
10033
10891
|
setGeneratingDocs(false);
|
|
10034
10892
|
}
|
|
10035
|
-
}, [
|
|
10893
|
+
}, [
|
|
10894
|
+
rpc,
|
|
10895
|
+
methods,
|
|
10896
|
+
t
|
|
10897
|
+
]);
|
|
10036
10898
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10037
10899
|
className: "app",
|
|
10038
|
-
children: [
|
|
10039
|
-
|
|
10040
|
-
onTransportChange: setTransport,
|
|
10041
|
-
onRefresh: refresh,
|
|
10042
|
-
loading,
|
|
10043
|
-
error,
|
|
10044
|
-
onGenerateDocs: generateDocs,
|
|
10045
|
-
generatingDocs
|
|
10046
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
|
|
10047
|
-
className: "sidebar",
|
|
10048
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10049
|
-
className: "view-switch segmented",
|
|
10050
|
-
role: "group",
|
|
10051
|
-
"aria-label": "视图",
|
|
10052
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
10053
|
-
type: "button",
|
|
10054
|
-
className: view === "methods" ? "active" : "",
|
|
10055
|
-
onClick: () => setView("methods"),
|
|
10056
|
-
children: "Methods"
|
|
10057
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
10058
|
-
type: "button",
|
|
10059
|
-
className: view === "metrics" ? "active" : "",
|
|
10060
|
-
onClick: () => setView("metrics"),
|
|
10061
|
-
children: "Metrics"
|
|
10062
|
-
})]
|
|
10063
|
-
}), view === "methods" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Methods" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MethodTree, {
|
|
10064
|
-
methods,
|
|
10065
|
-
selected,
|
|
10066
|
-
onSelect: setSelected
|
|
10067
|
-
})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10068
|
-
className: "metrics-sidebar",
|
|
10069
|
-
children: [
|
|
10070
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Metrics" }),
|
|
10071
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
10072
|
-
className: "hint",
|
|
10073
|
-
style: { margin: "0 0 8px" },
|
|
10074
|
-
children: "📊 服务端 RPC 调用统计。"
|
|
10075
|
-
}),
|
|
10076
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
10077
|
-
className: "metrics-filter",
|
|
10078
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
10079
|
-
className: "metrics-filter-label",
|
|
10080
|
-
children: "Filter"
|
|
10081
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
10082
|
-
className: "sf-input",
|
|
10083
|
-
type: "text",
|
|
10084
|
-
placeholder: "user.*, !system.*",
|
|
10085
|
-
value: methodFilter,
|
|
10086
|
-
onChange: (e) => setMethodFilter(e.target.value),
|
|
10087
|
-
spellCheck: false
|
|
10088
|
-
})]
|
|
10089
|
-
}),
|
|
10090
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
10091
|
-
className: "hint metrics-filter-help",
|
|
10092
|
-
children: [
|
|
10093
|
-
"支持 ",
|
|
10094
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "*" }),
|
|
10095
|
-
" / ",
|
|
10096
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "?" }),
|
|
10097
|
-
" / ",
|
|
10098
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "!" }),
|
|
10099
|
-
",多个模式用 ",
|
|
10100
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "," }),
|
|
10101
|
-
" 分隔。",
|
|
10102
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
|
|
10103
|
-
"例:",
|
|
10104
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "user.*" }),
|
|
10105
|
-
"、",
|
|
10106
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "*.get" }),
|
|
10107
|
-
"、",
|
|
10108
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "!system.*" }),
|
|
10109
|
-
"、",
|
|
10110
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: "user.*,!user.secret" })
|
|
10111
|
-
]
|
|
10112
|
-
}),
|
|
10113
|
-
metrics.snapshot && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", {
|
|
10114
|
-
className: "hint metrics-filter-stat",
|
|
10115
|
-
children: [
|
|
10116
|
-
"匹配 ",
|
|
10117
|
-
Object.keys(filteredSnapshot?.methods ?? {}).length,
|
|
10118
|
-
" /",
|
|
10119
|
-
" ",
|
|
10120
|
-
Object.keys(metrics.snapshot.methods).length,
|
|
10121
|
-
" 个方法"
|
|
10122
|
-
]
|
|
10123
|
-
})
|
|
10124
|
-
]
|
|
10125
|
-
})]
|
|
10126
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
10127
|
-
className: "content",
|
|
10128
|
-
children: view === "methods" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MethodDetail, {
|
|
10129
|
-
method: selected,
|
|
10130
|
-
detail
|
|
10131
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TestPanel, {
|
|
10132
|
-
method: selected,
|
|
10133
|
-
detail,
|
|
10134
|
-
rpc,
|
|
10900
|
+
children: [
|
|
10901
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Toolbar, {
|
|
10135
10902
|
transport,
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10903
|
+
onTransportChange: setTransport,
|
|
10904
|
+
onRefresh: refresh,
|
|
10905
|
+
loading,
|
|
10906
|
+
error,
|
|
10907
|
+
onGenerateDocs: generateDocs,
|
|
10908
|
+
generatingDocs
|
|
10909
|
+
}),
|
|
10910
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
|
|
10911
|
+
className: "sidebar",
|
|
10912
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10913
|
+
className: "view-switch segmented",
|
|
10914
|
+
role: "group",
|
|
10915
|
+
"aria-label": t("view.label"),
|
|
10916
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
10917
|
+
type: "button",
|
|
10918
|
+
className: view === "methods" ? "active" : "",
|
|
10919
|
+
onClick: () => setView("methods"),
|
|
10920
|
+
children: t("view.methods")
|
|
10921
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
|
|
10922
|
+
type: "button",
|
|
10923
|
+
className: view === "metrics" ? "active" : "",
|
|
10924
|
+
onClick: () => setView("metrics"),
|
|
10925
|
+
children: t("view.metrics")
|
|
10926
|
+
})]
|
|
10927
|
+
}), view === "methods" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10928
|
+
className: "metrics-sidebar",
|
|
10929
|
+
children: [
|
|
10930
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: t("sidebar.methods") }),
|
|
10931
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
10932
|
+
className: "metrics-filter",
|
|
10933
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
10934
|
+
className: "metrics-filter-label",
|
|
10935
|
+
children: t("sidebar.search")
|
|
10936
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
10937
|
+
className: "sf-input",
|
|
10938
|
+
type: "text",
|
|
10939
|
+
placeholder: t("sidebar.searchPlaceholder"),
|
|
10940
|
+
value: methodSearch,
|
|
10941
|
+
onChange: (e) => setMethodSearch(e.target.value),
|
|
10942
|
+
spellCheck: false
|
|
10943
|
+
})]
|
|
10944
|
+
}),
|
|
10945
|
+
!methodQuery.passthrough && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
10946
|
+
className: "hint metrics-filter-stat",
|
|
10947
|
+
children: t("sidebar.matchCount", {
|
|
10948
|
+
matched: filteredMethods.length,
|
|
10949
|
+
total: methods.length
|
|
10950
|
+
})
|
|
10951
|
+
}),
|
|
10952
|
+
filteredMethods.length === 0 && methods.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
10953
|
+
className: "empty",
|
|
10954
|
+
children: t("sidebar.noMatch")
|
|
10955
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MethodTree, {
|
|
10956
|
+
methods: filteredMethods,
|
|
10957
|
+
selected,
|
|
10958
|
+
onSelect: setSelected
|
|
10959
|
+
})
|
|
10960
|
+
]
|
|
10961
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
10962
|
+
className: "metrics-sidebar",
|
|
10963
|
+
children: [
|
|
10964
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: t("sidebar.metrics") }),
|
|
10965
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", {
|
|
10966
|
+
className: "metrics-filter",
|
|
10967
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
10968
|
+
className: "metrics-filter-label",
|
|
10969
|
+
children: t("sidebar.search")
|
|
10970
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
|
|
10971
|
+
className: "sf-input",
|
|
10972
|
+
type: "text",
|
|
10973
|
+
placeholder: t("sidebar.searchPlaceholder"),
|
|
10974
|
+
value: metricsSearch,
|
|
10975
|
+
onChange: (e) => setMetricsSearch(e.target.value),
|
|
10976
|
+
spellCheck: false
|
|
10977
|
+
})]
|
|
10978
|
+
}),
|
|
10979
|
+
metrics.snapshot && !metricsQuery.passthrough && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
|
|
10980
|
+
className: "hint metrics-filter-stat",
|
|
10981
|
+
children: t("sidebar.matchCount", {
|
|
10982
|
+
matched: Object.keys(filteredMetrics?.methods ?? {}).length,
|
|
10983
|
+
total: Object.keys(metrics.snapshot.methods).length
|
|
10984
|
+
})
|
|
10985
|
+
})
|
|
10986
|
+
]
|
|
10987
|
+
})]
|
|
10988
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
10989
|
+
className: "content",
|
|
10990
|
+
children: view === "methods" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MethodDetail, {
|
|
10991
|
+
method: selected,
|
|
10992
|
+
detail
|
|
10993
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TestPanel, {
|
|
10994
|
+
method: selected,
|
|
10995
|
+
detail,
|
|
10996
|
+
rpc,
|
|
10997
|
+
transport,
|
|
10998
|
+
endpoint: ENDPOINT
|
|
10999
|
+
})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MetricsPanel, {
|
|
11000
|
+
snapshot: filteredMetrics,
|
|
11001
|
+
previous: metrics.previous,
|
|
11002
|
+
fetchedAt: metrics.fetchedAt,
|
|
11003
|
+
loading: metrics.loading,
|
|
11004
|
+
error: metrics.error,
|
|
11005
|
+
available: metrics.available,
|
|
11006
|
+
onRefresh: () => void metrics.refresh(),
|
|
11007
|
+
autoRefresh: metrics.autoRefresh,
|
|
11008
|
+
onAutoRefreshChange: metrics.setAutoRefresh,
|
|
11009
|
+
intervalMs: metrics.intervalMs,
|
|
11010
|
+
onIntervalChange: metrics.setIntervalMs
|
|
11011
|
+
})
|
|
11012
|
+
})] }),
|
|
11013
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Footer, {})
|
|
11014
|
+
]
|
|
10151
11015
|
});
|
|
10152
11016
|
}
|
|
10153
11017
|
//#endregion
|
|
10154
11018
|
//#region webui/src/main.tsx
|
|
10155
|
-
import_client.createRoot(document.getElementById("root")).render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(App, {}) }) }));
|
|
11019
|
+
import_client.createRoot(document.getElementById("root")).render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(I18nProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(App, {}) }) }) }));
|
|
10156
11020
|
//#endregion
|
|
10157
11021
|
|
|
10158
|
-
//# sourceMappingURL=index-
|
|
11022
|
+
//# sourceMappingURL=index-CqI7vRAS.js.map
|