@yuhere/js-jsonrpc2 2.1.1 → 2.1.3

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.
Files changed (81) hide show
  1. package/dist/cli/cli.js +4 -4
  2. package/dist/cli/demo-methods.d.ts +1 -1
  3. package/dist/cli/demo-methods.js +1 -1
  4. package/dist/cli/express.js +2 -2
  5. package/dist/cli/stdio.js +1 -1
  6. package/dist/core/Repository.d.ts +2 -2
  7. package/dist/core/Repository.js +9 -9
  8. package/dist/core/convert.d.ts +2 -2
  9. package/dist/core/convert.js +2 -2
  10. package/dist/core/descriptor.d.ts +3 -3
  11. package/dist/core/descriptor.js +3 -3
  12. package/dist/core/index.d.ts +3 -3
  13. package/dist/core/index.js +2 -2
  14. package/dist/core/permission.d.ts +2 -2
  15. package/dist/core/permission.js +2 -2
  16. package/dist/core/spec-check.d.ts +1 -1
  17. package/dist/core/spec-check.js +3 -3
  18. package/dist/core/system-methods.d.ts +1 -1
  19. package/dist/core/system-methods.js +4 -4
  20. package/dist/errors/{RpcError.d.ts → RPCError.d.ts} +1 -1
  21. package/dist/errors/index.d.ts +2 -2
  22. package/dist/errors/index.js +2 -2
  23. package/dist/index.d.ts +11 -11
  24. package/dist/index.js +8 -8
  25. package/dist/schema/json/index.d.ts +16 -16
  26. package/dist/schema/json/index.js +4 -4
  27. package/dist/schema/json/marker.d.ts +1 -1
  28. package/dist/schema/z/protocol.d.ts +5 -5
  29. package/dist/schema/z/protocol.js +1 -1
  30. package/dist/schema/z/register.d.ts +1 -1
  31. package/dist/schema/z/register.js +1 -1
  32. package/dist/transport/express/body.js +2 -2
  33. package/dist/transport/express/index.d.ts +2 -2
  34. package/dist/transport/express/index.js +1 -1
  35. package/dist/transport/express/middleware.d.ts +2 -2
  36. package/dist/transport/express/middleware.js +5 -5
  37. package/dist/transport/express/respond.d.ts +1 -1
  38. package/dist/transport/express/respond.js +1 -1
  39. package/dist/transport/stdio/index.d.ts +1 -1
  40. package/dist/transport/stdio/index.js +1 -1
  41. package/dist/transport/stdio/middleware.d.ts +2 -2
  42. package/dist/transport/stdio/middleware.js +4 -4
  43. package/dist/transport/ws/index.d.ts +2 -2
  44. package/dist/transport/ws/index.js +2 -2
  45. package/dist/transport/ws/middleware.d.ts +2 -2
  46. package/dist/transport/ws/middleware.js +3 -3
  47. package/dist/transport/ws/standalone.d.ts +1 -1
  48. package/dist/transport/ws/standalone.js +2 -2
  49. package/dist/types.d.ts +4 -4
  50. package/htdoc/assets/{index-CQr-lnlD.js → index-BEVUmX2-.js} +170 -20
  51. package/htdoc/assets/index-BEVUmX2-.js.map +1 -0
  52. package/htdoc/index.html +1 -1
  53. package/package.json +8 -7
  54. package/webui/src/App.tsx +30 -3
  55. package/webui/src/api/docGen.ts +188 -0
  56. package/webui/src/components/SchemaForm.tsx +0 -1
  57. package/webui/src/components/Toolbar.tsx +13 -1
  58. package/dist/schema/index.d.ts +0 -4
  59. package/dist/schema/index.d.ts.map +0 -1
  60. package/dist/schema/index.js +0 -4
  61. package/dist/schema/index.js.map +0 -1
  62. package/dist/schema/primitives.d.ts +0 -25
  63. package/dist/schema/primitives.d.ts.map +0 -1
  64. package/dist/schema/primitives.js +0 -153
  65. package/dist/schema/primitives.js.map +0 -1
  66. package/dist/schema/rpc.d.ts +0 -21
  67. package/dist/schema/rpc.d.ts.map +0 -1
  68. package/dist/schema/rpc.js +0 -17
  69. package/dist/schema/rpc.js.map +0 -1
  70. package/dist/stream/index.d.ts +0 -3
  71. package/dist/stream/index.d.ts.map +0 -1
  72. package/dist/stream/index.js +0 -2
  73. package/dist/stream/index.js.map +0 -1
  74. package/dist/stream/stringify.d.ts +0 -19
  75. package/dist/stream/stringify.d.ts.map +0 -1
  76. package/dist/stream/stringify.js +0 -217
  77. package/dist/stream/stringify.js.map +0 -1
  78. package/htdoc/assets/index-CQr-lnlD.js.map +0 -1
  79. /package/dist/errors/{RpcError.d.ts.map → RPCError.d.ts.map} +0 -0
  80. /package/dist/errors/{RpcError.js → RPCError.js} +0 -0
  81. /package/dist/errors/{RpcError.js.map → RPCError.js.map} +0 -0
@@ -8129,7 +8129,7 @@ var THEME_OPTIONS = [
8129
8129
  label: "暗"
8130
8130
  }
8131
8131
  ];
8132
- function Toolbar({ transport, onTransportChange, onRefresh, loading, error }) {
8132
+ function Toolbar({ transport, onTransportChange, onRefresh, loading, error, onGenerateDocs, generatingDocs }) {
8133
8133
  const { mode, setMode } = useTheme();
8134
8134
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
8135
8135
  className: "toolbar",
@@ -8156,6 +8156,12 @@ function Toolbar({ transport, onTransportChange, onRefresh, loading, error }) {
8156
8156
  disabled: loading,
8157
8157
  children: loading ? "刷新中…" : "刷新方法列表"
8158
8158
  }),
8159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
8160
+ onClick: onGenerateDocs,
8161
+ disabled: generatingDocs || loading || loading,
8162
+ title: "拉取所有方法的帮助与签名,生成 Markdown 文档并下载",
8163
+ children: generatingDocs ? "生成中…" : "生成文档 ⬇"
8164
+ }),
8159
8165
  error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
8160
8166
  className: "error",
8161
8167
  children: error
@@ -8446,7 +8452,7 @@ function MethodDetail({ method, detail }) {
8446
8452
  //#endregion
8447
8453
  //#region webui/src/api/paramForm.ts
8448
8454
  /** 判断是否为合法 schema 描述(kind 为字符串) */
8449
- function isSchema(v) {
8455
+ function isSchema$1(v) {
8450
8456
  return !!v && typeof v === "object" && typeof v.kind === "string";
8451
8457
  }
8452
8458
  /**
@@ -8470,20 +8476,20 @@ function sampleFromSchema(schema) {
8470
8476
  const values = schema.constraints?.values;
8471
8477
  return Array.isArray(values) && values.length > 0 ? values[0] : "";
8472
8478
  }
8473
- case "nullable": return isSchema(c.inner) ? sampleFromSchema(c.inner) : null;
8474
- case "array": return [isSchema(c.items) ? sampleFromSchema(c.items) : null];
8475
- case "tuple": return (Array.isArray(c.items) ? c.items : []).map((it) => isSchema(it) ? sampleFromSchema(it) : null);
8479
+ case "nullable": return isSchema$1(c.inner) ? sampleFromSchema(c.inner) : null;
8480
+ case "array": return [isSchema$1(c.items) ? sampleFromSchema(c.items) : null];
8481
+ case "tuple": return (Array.isArray(c.items) ? c.items : []).map((it) => isSchema$1(it) ? sampleFromSchema(it) : null);
8476
8482
  case "union": {
8477
8483
  const options = Array.isArray(c.options) ? c.options : [];
8478
- return options.length > 0 && isSchema(options[0]) ? sampleFromSchema(options[0]) : null;
8484
+ return options.length > 0 && isSchema$1(options[0]) ? sampleFromSchema(options[0]) : null;
8479
8485
  }
8480
8486
  case "object": {
8481
8487
  const props = c.properties ?? {};
8482
8488
  const out = {};
8483
- for (const [k, v] of Object.entries(props)) if (isSchema(v)) out[k] = sampleFromSchema(v);
8489
+ for (const [k, v] of Object.entries(props)) if (isSchema$1(v)) out[k] = sampleFromSchema(v);
8484
8490
  return out;
8485
8491
  }
8486
- case "record": return { key: isSchema(c.values) ? sampleFromSchema(c.values) : null };
8492
+ case "record": return { key: isSchema$1(c.values) ? sampleFromSchema(c.values) : null };
8487
8493
  default: return null;
8488
8494
  }
8489
8495
  }
@@ -8531,7 +8537,7 @@ function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen =
8531
8537
  const [open, setOpen] = (0, import_react.useState)(defaultOpen);
8532
8538
  const kind = schema.kind;
8533
8539
  if (kind === "nullable") {
8534
- const inner = schema.children && isSchema(schema.children.inner) ? schema.children.inner : void 0;
8540
+ const inner = schema.children && isSchema$1(schema.children.inner) ? schema.children.inner : void 0;
8535
8541
  if (!inner) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UnknownLeaf, {
8536
8542
  schema,
8537
8543
  value,
@@ -8556,10 +8562,6 @@ function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen =
8556
8562
  style: { color: colorOf("nullable") },
8557
8563
  children: "nullable"
8558
8564
  }),
8559
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
8560
- className: "sf-nullable",
8561
- children: "| null"
8562
- }),
8563
8565
  !isNull && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
8564
8566
  type: "button",
8565
8567
  className: "tiny",
@@ -8623,7 +8625,7 @@ function SchemaField({ schema, value, onChange, label, depth = 0, defaultOpen =
8623
8625
  })]
8624
8626
  });
8625
8627
  if (kind === "union") {
8626
- const options = Array.isArray(schema.children?.options) ? schema.children.options.filter(isSchema) : [];
8628
+ const options = Array.isArray(schema.children?.options) ? schema.children.options.filter(isSchema$1) : [];
8627
8629
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
8628
8630
  className: "sf-node sf-row",
8629
8631
  style: { paddingLeft: depth * 14 },
@@ -8799,7 +8801,7 @@ function UnionField({ options, value, onChange, depth, disabled }) {
8799
8801
  function ContainerChildren({ schema, value, onChange, depth, disabled }) {
8800
8802
  const c = schema.children ?? {};
8801
8803
  if (schema.kind === "array") {
8802
- const itemSchema = isSchema(c.items) ? c.items : void 0;
8804
+ const itemSchema = isSchema$1(c.items) ? c.items : void 0;
8803
8805
  if (!itemSchema) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
8804
8806
  className: "hint",
8805
8807
  children: "(数组无 item schema)"
@@ -8835,7 +8837,7 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
8835
8837
  })] });
8836
8838
  }
8837
8839
  if (schema.kind === "tuple") {
8838
- const items = Array.isArray(c.items) ? c.items.filter(isSchema) : [];
8840
+ const items = Array.isArray(c.items) ? c.items.filter(isSchema$1) : [];
8839
8841
  const arr = Array.isArray(value) ? value : [];
8840
8842
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: items.map((itemSchema, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaField, {
8841
8843
  schema: itemSchema,
@@ -8856,7 +8858,7 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
8856
8858
  const obj = value && typeof value === "object" && !Array.isArray(value) ? value : {};
8857
8859
  const strict = Boolean(schema.constraints?.strict);
8858
8860
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [Object.entries(props).map(([key, prop]) => {
8859
- if (!isSchema(prop)) return null;
8861
+ if (!isSchema$1(prop)) return null;
8860
8862
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SchemaField, {
8861
8863
  schema: prop,
8862
8864
  value: obj[key],
@@ -8881,7 +8883,7 @@ function ContainerChildren({ schema, value, onChange, depth, disabled }) {
8881
8883
  })] });
8882
8884
  }
8883
8885
  if (schema.kind === "record") {
8884
- const valueSchema = isSchema(c.values) ? c.values : void 0;
8886
+ const valueSchema = isSchema$1(c.values) ? c.values : void 0;
8885
8887
  if (!valueSchema) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
8886
8888
  className: "hint",
8887
8889
  children: "(record 无 value schema)"
@@ -9232,11 +9234,142 @@ function formatError(e) {
9232
9234
  return `Error: ${e instanceof Error ? e.message : String(e)}`;
9233
9235
  }
9234
9236
  //#endregion
9237
+ //#region webui/src/api/docGen.ts
9238
+ function isSchema(v) {
9239
+ return !!v && typeof v === "object" && typeof v.kind === "string";
9240
+ }
9241
+ /** 逐个方法拉取 help + signature */
9242
+ async function collectApiDoc(rpc, methods, onProgress) {
9243
+ const out = [];
9244
+ for (let i = 0; i < methods.length; i++) {
9245
+ const name = methods[i];
9246
+ try {
9247
+ const [help, sig] = await Promise.all([rpc.call("system.methodHelp", name).catch(() => ""), rpc.call("system.methodSignature", name).catch(() => [])]);
9248
+ out.push({
9249
+ name,
9250
+ help: typeof help === "string" ? help : "",
9251
+ signature: Array.isArray(sig) ? sig.filter(isSchema) : []
9252
+ });
9253
+ } catch (e) {
9254
+ out.push({
9255
+ name,
9256
+ help: "",
9257
+ signature: [],
9258
+ error: e instanceof Error ? e.message : String(e)
9259
+ });
9260
+ }
9261
+ onProgress?.(i + 1, methods.length);
9262
+ }
9263
+ return {
9264
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
9265
+ methods: out
9266
+ };
9267
+ }
9268
+ function renderSchemaTree(schema, indent = 0) {
9269
+ const pad = " ".repeat(indent);
9270
+ const lines = [];
9271
+ let head = `${pad}- \`${schema.kind}\``;
9272
+ if (schema.nullable) head += " _(nullable)_";
9273
+ if (schema.description) head += ` — ${schema.description}`;
9274
+ const c = schema.constraints;
9275
+ if (c && Object.keys(c).length > 0) {
9276
+ const parts = Object.entries(c).filter(([, v]) => v !== void 0).map(([k, v]) => `${k}=${JSON.stringify(v)}`);
9277
+ if (parts.length) head += ` \`{ ${parts.join(", ")} }\``;
9278
+ }
9279
+ lines.push(head);
9280
+ const ch = schema.children ?? {};
9281
+ const pushChild = (label, child) => {
9282
+ const sub = renderSchemaTree(child, indent + 1);
9283
+ if (sub.length) {
9284
+ sub[0] = `${" ".repeat(indent + 1)}- **${label}**: ${sub[0].trim().replace(/^- /, "")}`;
9285
+ lines.push(...sub);
9286
+ }
9287
+ };
9288
+ if (isSchema(ch.inner)) pushChild("inner", ch.inner);
9289
+ if (Array.isArray(ch.items)) ch.items.forEach((it, i) => {
9290
+ if (isSchema(it)) pushChild(`[${i}]`, it);
9291
+ });
9292
+ else if (isSchema(ch.items)) pushChild("items", ch.items);
9293
+ if (Array.isArray(ch.options)) ch.options.forEach((opt, i) => {
9294
+ if (isSchema(opt)) pushChild(`option[${i}]`, opt);
9295
+ });
9296
+ if (ch.properties && typeof ch.properties === "object") {
9297
+ for (const [k, v] of Object.entries(ch.properties)) if (isSchema(v)) pushChild(k, v);
9298
+ }
9299
+ if (isSchema(ch.values)) pushChild("values", ch.values);
9300
+ return lines;
9301
+ }
9302
+ function renderMarkdown(doc) {
9303
+ const lines = [];
9304
+ lines.push("# JSON-RPC API 文档");
9305
+ lines.push("");
9306
+ lines.push(`> 生成时间:${doc.generatedAt}`);
9307
+ lines.push(`> 方法总数:${doc.methods.length}`);
9308
+ lines.push("");
9309
+ lines.push("## 目录");
9310
+ lines.push("");
9311
+ for (const m of doc.methods) {
9312
+ const anchor = m.name.toLowerCase().replace(/[^\w]+/g, "-");
9313
+ lines.push(`- [\`${m.name}\`](#${anchor})`);
9314
+ }
9315
+ lines.push("");
9316
+ for (const m of doc.methods) {
9317
+ lines.push(`## \`${m.name}\``);
9318
+ lines.push("");
9319
+ if (m.error) {
9320
+ lines.push(`> ⚠️ 获取失败:${m.error}`);
9321
+ lines.push("");
9322
+ continue;
9323
+ }
9324
+ lines.push("**帮助**");
9325
+ lines.push("");
9326
+ lines.push(m.help ? m.help : "_(无帮助信息)_");
9327
+ lines.push("");
9328
+ if (m.signature.length === 0) {
9329
+ lines.push("**签名**:_(无)_");
9330
+ lines.push("");
9331
+ continue;
9332
+ }
9333
+ const [ret, ...params] = m.signature;
9334
+ lines.push("**返回类型**");
9335
+ lines.push("");
9336
+ lines.push(...renderSchemaTree(ret, 0));
9337
+ lines.push("");
9338
+ lines.push(`**参数**(${params.length} 个)`);
9339
+ lines.push("");
9340
+ if (params.length === 0) lines.push("_(无参数)_");
9341
+ else params.forEach((p, i) => {
9342
+ const sub = renderSchemaTree(p, 0);
9343
+ if (sub.length) {
9344
+ sub[0] = `- **参数 [${i}]**: ${sub[0].trim().replace(/^- /, "")}`;
9345
+ lines.push(...sub);
9346
+ }
9347
+ });
9348
+ lines.push("");
9349
+ lines.push("---");
9350
+ lines.push("");
9351
+ }
9352
+ return lines.join("\n");
9353
+ }
9354
+ /** 触发浏览器下载 */
9355
+ function downloadText(filename, text, mime = "text/plain") {
9356
+ const blob = new Blob([text], { type: `${mime};charset=utf-8` });
9357
+ const url = URL.createObjectURL(blob);
9358
+ const a = document.createElement("a");
9359
+ a.href = url;
9360
+ a.download = filename;
9361
+ document.body.appendChild(a);
9362
+ a.click();
9363
+ document.body.removeChild(a);
9364
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
9365
+ }
9366
+ //#endregion
9235
9367
  //#region webui/src/App.tsx
9236
9368
  var ENDPOINT = "";
9237
9369
  function App() {
9238
9370
  const [transport, setTransport] = (0, import_react.useState)("http");
9239
9371
  const [selected, setSelected] = (0, import_react.useState)("");
9372
+ const [generatingDocs, setGeneratingDocs] = (0, import_react.useState)(false);
9240
9373
  const rpc = (0, import_react.useMemo)(() => {
9241
9374
  return createRpc({
9242
9375
  transport,
@@ -9248,6 +9381,21 @@ function App() {
9248
9381
  }, [rpc]);
9249
9382
  const { methods, loading, error, refresh } = useMethods(rpc);
9250
9383
  const detail = useMethodDetail(rpc, selected);
9384
+ const generateDocs = (0, import_react.useCallback)(async () => {
9385
+ if (methods.length === 0) {
9386
+ alert("方法列表为空,请先刷新方法列表。");
9387
+ return;
9388
+ }
9389
+ setGeneratingDocs(true);
9390
+ try {
9391
+ const md = renderMarkdown(await collectApiDoc(rpc, methods));
9392
+ downloadText(`jsonrpc-api-doc-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}.md`, md, "text/markdown");
9393
+ } catch (e) {
9394
+ alert(`生成文档失败:${e instanceof Error ? e.message : String(e)}`);
9395
+ } finally {
9396
+ setGeneratingDocs(false);
9397
+ }
9398
+ }, [rpc, methods]);
9251
9399
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
9252
9400
  className: "app",
9253
9401
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Toolbar, {
@@ -9255,7 +9403,9 @@ function App() {
9255
9403
  onTransportChange: setTransport,
9256
9404
  onRefresh: refresh,
9257
9405
  loading,
9258
- error
9406
+ error,
9407
+ onGenerateDocs: generateDocs,
9408
+ generatingDocs
9259
9409
  }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("aside", {
9260
9410
  className: "sidebar",
9261
9411
  children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Methods" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MethodTree, {
@@ -9283,4 +9433,4 @@ function App() {
9283
9433
  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, {}) }) }));
9284
9434
  //#endregion
9285
9435
 
9286
- //# sourceMappingURL=index-CQr-lnlD.js.map
9436
+ //# sourceMappingURL=index-BEVUmX2-.js.map