@yuhere/js-jsonrpc2 2.1.2 → 2.1.4

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 (84) 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-hcP2-9jw.css → index-BAZmvr5x.css} +13 -0
  51. package/htdoc/assets/{index-CQr-lnlD.js → index-sVQlhxjI.js} +223 -32
  52. package/htdoc/assets/index-sVQlhxjI.js.map +1 -0
  53. package/htdoc/index.html +2 -2
  54. package/package.json +5 -4
  55. package/webui/src/App.tsx +30 -3
  56. package/webui/src/api/docGen.ts +188 -0
  57. package/webui/src/components/SchemaForm.tsx +0 -1
  58. package/webui/src/components/TestPanel.tsx +53 -10
  59. package/webui/src/components/Toolbar.tsx +13 -1
  60. package/webui/src/styles/geek.css +13 -0
  61. package/dist/schema/index.d.ts +0 -4
  62. package/dist/schema/index.d.ts.map +0 -1
  63. package/dist/schema/index.js +0 -4
  64. package/dist/schema/index.js.map +0 -1
  65. package/dist/schema/primitives.d.ts +0 -25
  66. package/dist/schema/primitives.d.ts.map +0 -1
  67. package/dist/schema/primitives.js +0 -153
  68. package/dist/schema/primitives.js.map +0 -1
  69. package/dist/schema/rpc.d.ts +0 -21
  70. package/dist/schema/rpc.d.ts.map +0 -1
  71. package/dist/schema/rpc.js +0 -17
  72. package/dist/schema/rpc.js.map +0 -1
  73. package/dist/stream/index.d.ts +0 -3
  74. package/dist/stream/index.d.ts.map +0 -1
  75. package/dist/stream/index.js +0 -2
  76. package/dist/stream/index.js.map +0 -1
  77. package/dist/stream/stringify.d.ts +0 -19
  78. package/dist/stream/stringify.d.ts.map +0 -1
  79. package/dist/stream/stringify.js +0 -217
  80. package/dist/stream/stringify.js.map +0 -1
  81. package/htdoc/assets/index-CQr-lnlD.js.map +0 -1
  82. /package/dist/errors/{RpcError.d.ts.map → RPCError.d.ts.map} +0 -0
  83. /package/dist/errors/{RpcError.js → RPCError.js} +0 -0
  84. /package/dist/errors/{RpcError.js.map → RPCError.js.map} +0 -0
package/htdoc/index.html CHANGED
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>JSON-RPC 2.0</title>
7
- <script type="module" crossorigin src="./assets/index-CQr-lnlD.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/index-hcP2-9jw.css">
7
+ <script type="module" crossorigin src="./assets/index-sVQlhxjI.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-BAZmvr5x.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuhere/js-jsonrpc2",
3
- "version": "2.1.2",
3
+ "version": "2.1.4",
4
4
  "description": "A TypeScript JSON-RPC 2.0 server library with schema validation, authorization, dependency injection, and multiple transports.",
5
5
  "homepage": "https://github.com/yuhere/js-jsonrpc2#readme",
6
6
  "license": "MIT",
@@ -40,8 +40,8 @@
40
40
  "js-jsonrpc2": "./dist/cli.js"
41
41
  },
42
42
  "scripts": {
43
- "build": "npm run build:lib && npm run build:webui",
44
- "build:lib": "tsc -p tsconfig.build.json",
43
+ "build": "clean && npm run build:lib && npm run build:webui",
44
+ "build:lib": "tsc -p tsconfig.build.json && tsc-esm-fix",
45
45
  "build:webui": "tsc -p webui//tsconfig.json && vite build --config webui/vite.config.ts",
46
46
  "dev": "run-p dev:lib dev:webui",
47
47
  "dev:lib": "tsx src/cli/express.ts",
@@ -78,6 +78,7 @@
78
78
  "react": "^18.3.1",
79
79
  "react-dom": "^18.3.1",
80
80
  "supertest": "^7.3.1",
81
+ "tsc-esm-fix": "^3.1.2",
81
82
  "tsx": "^4.23.15",
82
83
  "typescript": "^7.0.2",
83
84
  "vite": "^8.3.5",
@@ -89,4 +90,4 @@
89
90
  "ws": "^8.22.0",
90
91
  "zod": "^4.6.7"
91
92
  }
92
- }
93
+ }
package/webui/src/App.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { useEffect, useMemo, useState } from 'react';
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { createRpc, type TransportKind } from './api/rpc';
3
3
  import { useMethods } from './hooks/useMethods';
4
4
  import { useMethodDetail } from './hooks/useMethodDetail';
@@ -6,14 +6,18 @@ import { Toolbar } from './components/Toolbar';
6
6
  import { MethodTree } from './components/MethodTree';
7
7
  import { MethodDetail } from './components/MethodDetail';
8
8
  import { TestPanel } from './components/TestPanel';
9
+ import {
10
+ collectApiDoc,
11
+ downloadText,
12
+ renderMarkdown,
13
+ } from './api/docGen';
9
14
 
10
15
  const ENDPOINT = '';
11
- // 如需强制指定 WS 地址,可改为例如 'ws://localhost:3000/'
12
- // 默认由 wsTransport 从 window.location 推导。
13
16
 
14
17
  export default function App() {
15
18
  const [transport, setTransport] = useState<TransportKind>('http');
16
19
  const [selected, setSelected] = useState('');
20
+ const [generatingDocs, setGeneratingDocs] = useState(false);
17
21
 
18
22
  const rpc = useMemo(() => {
19
23
  return createRpc({ transport, endpoint: ENDPOINT });
@@ -26,6 +30,27 @@ export default function App() {
26
30
  const { methods, loading, error, refresh } = useMethods(rpc);
27
31
  const detail = useMethodDetail(rpc, selected);
28
32
 
33
+ const generateDocs = useCallback(async () => {
34
+ if (methods.length === 0) {
35
+ alert('方法列表为空,请先刷新方法列表。');
36
+ return;
37
+ }
38
+ setGeneratingDocs(true);
39
+ try {
40
+ const doc = await collectApiDoc(rpc, methods);
41
+ const md = renderMarkdown(doc);
42
+ const ts = new Date()
43
+ .toISOString()
44
+ .replace(/[:.]/g, '-')
45
+ .slice(0, 19);
46
+ downloadText(`jsonrpc-api-doc-${ts}.md`, md, 'text/markdown');
47
+ } catch (e) {
48
+ alert(`生成文档失败:${e instanceof Error ? e.message : String(e)}`);
49
+ } finally {
50
+ setGeneratingDocs(false);
51
+ }
52
+ }, [rpc, methods]);
53
+
29
54
  return (
30
55
  <div className="app">
31
56
  <Toolbar
@@ -34,6 +59,8 @@ export default function App() {
34
59
  onRefresh={refresh}
35
60
  loading={loading}
36
61
  error={error}
62
+ onGenerateDocs={generateDocs}
63
+ generatingDocs={generatingDocs}
37
64
  />
38
65
  <main>
39
66
  <aside className="sidebar">
@@ -0,0 +1,188 @@
1
+ import type { RpcClient } from './rpc';
2
+ import type { SchemaDescription } from './schema';
3
+
4
+ export interface MethodDoc {
5
+ name: string;
6
+ help: string;
7
+ signature: SchemaDescription[];
8
+ error?: string;
9
+ }
10
+
11
+ export interface ApiDoc {
12
+ generatedAt: string;
13
+ methods: MethodDoc[];
14
+ }
15
+
16
+ function isSchema(v: unknown): v is SchemaDescription {
17
+ return !!v && typeof v === 'object' && typeof (v as SchemaDescription).kind === 'string';
18
+ }
19
+
20
+ /** 逐个方法拉取 help + signature */
21
+ export async function collectApiDoc(
22
+ rpc: RpcClient,
23
+ methods: string[],
24
+ onProgress?: (done: number, total: number) => void,
25
+ ): Promise<ApiDoc> {
26
+ const out: MethodDoc[] = [];
27
+ for (let i = 0; i < methods.length; i++) {
28
+ const name = methods[i];
29
+ try {
30
+ const [help, sig] = await Promise.all([
31
+ rpc.call<string>('system.methodHelp', name).catch(() => ''),
32
+ rpc.call<unknown[]>('system.methodSignature', name).catch(() => []),
33
+ ]);
34
+ out.push({
35
+ name,
36
+ help: typeof help === 'string' ? help : '',
37
+ signature: Array.isArray(sig) ? sig.filter(isSchema) : [],
38
+ });
39
+ } catch (e) {
40
+ out.push({
41
+ name,
42
+ help: '',
43
+ signature: [],
44
+ error: e instanceof Error ? e.message : String(e),
45
+ });
46
+ }
47
+ onProgress?.(i + 1, methods.length);
48
+ }
49
+ return { generatedAt: new Date().toISOString(), methods: out };
50
+ }
51
+
52
+ // ─────────────────────────────────────────────────────────────
53
+ // Markdown 渲染
54
+ // ─────────────────────────────────────────────────────────────
55
+
56
+ function renderSchema(schema: SchemaDescription): string {
57
+ // 简单的单行描述:kind + constraints + nullable
58
+ let s = schema.kind;
59
+ if (schema.nullable) s += ' | null';
60
+ const c = schema.constraints;
61
+ if (c && Object.keys(c).length > 0) {
62
+ const parts = Object.entries(c)
63
+ .filter(([, v]) => v !== undefined)
64
+ .map(([k, v]) => `${k}=${JSON.stringify(v)}`);
65
+ if (parts.length) s += ` { ${parts.join(', ')} }`;
66
+ }
67
+ return s;
68
+ }
69
+
70
+ function renderSchemaTree(schema: SchemaDescription, indent = 0): string[] {
71
+ const pad = ' '.repeat(indent);
72
+ const lines: string[] = [];
73
+ let head = `${pad}- \`${schema.kind}\``;
74
+ if (schema.nullable) head += ' _(nullable)_';
75
+ if (schema.description) head += ` — ${schema.description}`;
76
+ const c = schema.constraints;
77
+ if (c && Object.keys(c).length > 0) {
78
+ const parts = Object.entries(c)
79
+ .filter(([, v]) => v !== undefined)
80
+ .map(([k, v]) => `${k}=${JSON.stringify(v)}`);
81
+ if (parts.length) head += ` \`{ ${parts.join(', ')} }\``;
82
+ }
83
+ lines.push(head);
84
+
85
+ const ch = schema.children ?? {};
86
+ const pushChild = (label: string, child: SchemaDescription) => {
87
+ const sub = renderSchemaTree(child, indent + 1);
88
+ if (sub.length) {
89
+ sub[0] = `${' '.repeat(indent + 1)}- **${label}**: ${sub[0].trim().replace(/^- /, '')}`;
90
+ lines.push(...sub);
91
+ }
92
+ };
93
+
94
+ if (isSchema(ch.inner)) pushChild('inner', ch.inner);
95
+ if (Array.isArray(ch.items)) {
96
+ (ch.items as unknown[]).forEach((it, i) => {
97
+ if (isSchema(it)) pushChild(`[${i}]`, it);
98
+ });
99
+ } else if (isSchema(ch.items)) {
100
+ pushChild('items', ch.items);
101
+ }
102
+ if (Array.isArray(ch.options)) {
103
+ (ch.options as unknown[]).forEach((opt, i) => {
104
+ if (isSchema(opt)) pushChild(`option[${i}]`, opt);
105
+ });
106
+ }
107
+ if (ch.properties && typeof ch.properties === 'object') {
108
+ for (const [k, v] of Object.entries(ch.properties)) {
109
+ if (isSchema(v)) pushChild(k, v);
110
+ }
111
+ }
112
+ if (isSchema(ch.values)) pushChild('values', ch.values);
113
+
114
+ return lines;
115
+ }
116
+
117
+ export function renderMarkdown(doc: ApiDoc): string {
118
+ const lines: string[] = [];
119
+ lines.push('# JSON-RPC API 文档');
120
+ lines.push('');
121
+ lines.push(`> 生成时间:${doc.generatedAt}`);
122
+ lines.push(`> 方法总数:${doc.methods.length}`);
123
+ lines.push('');
124
+ lines.push('## 目录');
125
+ lines.push('');
126
+ for (const m of doc.methods) {
127
+ const anchor = m.name.toLowerCase().replace(/[^\w]+/g, '-');
128
+ lines.push(`- [\`${m.name}\`](#${anchor})`);
129
+ }
130
+ lines.push('');
131
+
132
+ for (const m of doc.methods) {
133
+ lines.push(`## \`${m.name}\``);
134
+ lines.push('');
135
+ if (m.error) {
136
+ lines.push(`> ⚠️ 获取失败:${m.error}`);
137
+ lines.push('');
138
+ continue;
139
+ }
140
+ lines.push('**帮助**');
141
+ lines.push('');
142
+ lines.push(m.help ? m.help : '_(无帮助信息)_');
143
+ lines.push('');
144
+
145
+ if (m.signature.length === 0) {
146
+ lines.push('**签名**:_(无)_');
147
+ lines.push('');
148
+ continue;
149
+ }
150
+
151
+ const [ret, ...params] = m.signature;
152
+ lines.push('**返回类型**');
153
+ lines.push('');
154
+ lines.push(...renderSchemaTree(ret, 0));
155
+ lines.push('');
156
+ lines.push(`**参数**(${params.length} 个)`);
157
+ lines.push('');
158
+ if (params.length === 0) {
159
+ lines.push('_(无参数)_');
160
+ } else {
161
+ params.forEach((p, i) => {
162
+ const sub = renderSchemaTree(p, 0);
163
+ if (sub.length) {
164
+ sub[0] = `- **参数 [${i}]**: ${sub[0].trim().replace(/^- /, '')}`;
165
+ lines.push(...sub);
166
+ }
167
+ });
168
+ }
169
+ lines.push('');
170
+ lines.push('---');
171
+ lines.push('');
172
+ }
173
+
174
+ return lines.join('\n');
175
+ }
176
+
177
+ /** 触发浏览器下载 */
178
+ export function downloadText(filename: string, text: string, mime = 'text/plain') {
179
+ const blob = new Blob([text], { type: `${mime};charset=utf-8` });
180
+ const url = URL.createObjectURL(blob);
181
+ const a = document.createElement('a');
182
+ a.href = url;
183
+ a.download = filename;
184
+ document.body.appendChild(a);
185
+ a.click();
186
+ document.body.removeChild(a);
187
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
188
+ }
@@ -120,7 +120,6 @@ function SchemaField({
120
120
  <span className="sf-kind" style={{ color: colorOf('nullable') }}>
121
121
  nullable
122
122
  </span>
123
- <span className="sf-nullable">| null</span>
124
123
  {!isNull && (
125
124
  <button
126
125
  type="button"
@@ -20,6 +20,12 @@ const COPY_OPTIONS: { value: CopyKind; label: string }[] = [
20
20
  { value: 'fetch', label: '复制 fetch' },
21
21
  ];
22
22
 
23
+ /** 格式化耗时:<1s 用 ms,否则用 s */
24
+ function formatElapsed(ms: number): string {
25
+ if (ms < 1000) return `${ms.toFixed(0)} ms`;
26
+ return `${(ms / 1000).toFixed(2)} s`;
27
+ }
28
+
23
29
  export function TestPanel({
24
30
  method,
25
31
  detail,
@@ -32,6 +38,7 @@ export function TestPanel({
32
38
 
33
39
  const [values, setValues] = useState<unknown[]>([]);
34
40
  const [output, setOutput] = useState('');
41
+ const [elapsed, setElapsed] = useState<{ total: number; firstFrame?: number } | null>(null);
35
42
  const [running, setRunning] = useState(false);
36
43
  const [copyKind, setCopyKind] = useState<CopyKind>('curl');
37
44
  const [copied, setCopied] = useState(false);
@@ -44,6 +51,7 @@ export function TestPanel({
44
51
  if (!method) return;
45
52
  setValues(paramSchemas.map(sampleFromSchema));
46
53
  setOutput('');
54
+ setElapsed(null);
47
55
  }, [method, paramSchemas]);
48
56
 
49
57
  useEffect(() => {
@@ -76,29 +84,46 @@ export function TestPanel({
76
84
  if (!method) return;
77
85
  setRunning(true);
78
86
  setOutput('');
87
+ setElapsed(null);
88
+
89
+ const startedAt = performance.now();
79
90
  try {
80
91
  const result = await rpc.call(method, ...values);
92
+
93
+ // 首帧/响应到达耗时
94
+ const firstFrameAt = performance.now() - startedAt;
95
+
81
96
  if (isStreamResult(result)) {
82
97
  let idx = 0;
83
98
  const lines: string[] = [];
99
+
100
+ // 每帧记录到达时间
84
101
  for await (const value of result) {
85
- lines.push(`[${idx}] ${JSON.stringify(value, null, 2)}`);
102
+ const now = performance.now() - startedAt;
103
+ lines.push(
104
+ `[${idx}] (+${formatElapsed(now)}) ${JSON.stringify(value, null, 2)}`,
105
+ );
86
106
  idx++;
87
107
  setOutput(lines.join('\n'));
88
108
  }
89
- if (idx === 0) setOutput('(流已结束,无数据)');
90
- else lines.push(`(流已结束,共 ${idx} 帧)`), setOutput(lines.join('\n'));
91
- } else {
92
- setOutput(JSON.stringify(result, null, 2));
93
- }
94
109
 
95
- if (isStreamReturn) {
110
+ const totalAt = performance.now() - startedAt;
111
+ if (idx === 0) {
112
+ lines.push(`(流已结束,无数据,总耗时 ${formatElapsed(totalAt)})`);
113
+ } else {
114
+ lines.push(`(流已结束,共 ${idx} 帧,总耗时 ${formatElapsed(totalAt)})`);
115
+ }
116
+ setOutput(lines.join('\n'));
117
+ setElapsed({ total: totalAt, firstFrame: firstFrameAt });
96
118
  } else {
97
- const result = await rpc.call(method, ...values);
119
+ const totalAt = performance.now() - startedAt;
98
120
  setOutput(JSON.stringify(result, null, 2));
121
+ setElapsed({ total: totalAt });
99
122
  }
100
123
  } catch (e) {
124
+ const totalAt = performance.now() - startedAt;
101
125
  setOutput(formatError(e));
126
+ setElapsed({ total: totalAt });
102
127
  } finally {
103
128
  setRunning(false);
104
129
  requestAnimationFrame(() =>
@@ -211,12 +236,30 @@ export function TestPanel({
211
236
  >
212
237
  重置为示例
213
238
  </button>
214
- <button onClick={() => setOutput('')} disabled={!output}>
239
+ <button
240
+ onClick={() => {
241
+ setOutput('');
242
+ setElapsed(null);
243
+ }}
244
+ disabled={!output && !elapsed}
245
+ >
215
246
  清空输出
216
247
  </button>
217
248
  </div>
218
249
 
219
- <h3>结果{isStreamReturn && <span className="hint">(流式)</span>}</h3>
250
+ <h3>
251
+ 结果{isStreamReturn && <span className="hint">(流式)</span>}
252
+ {elapsed && (
253
+ <span className="elapsed-badge">
254
+ {' '}⏱ {formatElapsed(elapsed.total)}
255
+ {elapsed.firstFrame !== undefined && (
256
+ <span className="hint">
257
+ {' '}· 首帧 {formatElapsed(elapsed.firstFrame)}
258
+ </span>
259
+ )}
260
+ </span>
261
+ )}
262
+ </h3>
220
263
  <pre className="output" ref={outRef}>
221
264
  {output || '(尚未执行)'}
222
265
  </pre>
@@ -7,6 +7,9 @@ interface ToolbarProps {
7
7
  onRefresh: () => void;
8
8
  loading: boolean;
9
9
  error: string | null;
10
+ /** 新增:生成文档 */
11
+ onGenerateDocs: () => void;
12
+ generatingDocs: boolean;
10
13
  }
11
14
 
12
15
  const THEME_OPTIONS: { value: ThemeMode; label: string }[] = [
@@ -21,6 +24,8 @@ export function Toolbar({
21
24
  onRefresh,
22
25
  loading,
23
26
  error,
27
+ onGenerateDocs,
28
+ generatingDocs,
24
29
  }: ToolbarProps) {
25
30
  const { mode, setMode } = useTheme();
26
31
 
@@ -49,9 +54,16 @@ export function Toolbar({
49
54
  {loading ? '刷新中…' : '刷新方法列表'}
50
55
  </button>
51
56
 
57
+ <button
58
+ onClick={onGenerateDocs}
59
+ disabled={generatingDocs || loading || loading /* methods 空时由 App 拦截 */}
60
+ title="拉取所有方法的帮助与签名,生成 Markdown 文档并下载"
61
+ >
62
+ {generatingDocs ? '生成中…' : '生成文档 ⬇'}
63
+ </button>
64
+
52
65
  {error && <span className="error">{error}</span>}
53
66
 
54
- {/* 主题下拉,放右上角 */}
55
67
  <label className="theme-select" title="主题">
56
68
  <span className="theme-select-label">主题</span>
57
69
  <select
@@ -726,4 +726,17 @@ textarea:focus {
726
726
  .split-button {
727
727
  display: inline-flex;
728
728
  }
729
+ }
730
+
731
+ /* ---- 耗时徽章(TestPanel 结果区) ---- */
732
+ .elapsed-badge {
733
+ color: var(--syn-number);
734
+ font-size: 12px;
735
+ font-weight: normal;
736
+ letter-spacing: 0;
737
+ text-transform: none;
738
+ }
739
+
740
+ .elapsed-badge .hint {
741
+ font-size: 11px;
729
742
  }
@@ -1,4 +0,0 @@
1
- export * from './primitives';
2
- export * from './rpc';
3
- export { z } from 'zod';
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
@@ -1,4 +0,0 @@
1
- export * from './primitives';
2
- export * from './rpc';
3
- export { z } from 'zod';
4
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC"}
@@ -1,25 +0,0 @@
1
- import type { ParamSchema } from '../types';
2
- export interface ParamMeta {
3
- kind?: 'void' | 'any' | 'array' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'arrayOf' | 'objectOf' | 'shape' | 'oneOf' | 'oneOfType' | 'instanceOf' | 'injectable';
4
- naming?: string;
5
- required?: 'none' | 'isRequired' | 'isRequiredNotNull';
6
- injectable?: string;
7
- of?: unknown;
8
- }
9
- export declare function getMeta(schema: ParamSchema): ParamMeta;
10
- export declare function setJSONString(schema: ParamSchema, description: string): ParamSchema;
11
- export declare function toJSONString(schema: ParamSchema): string;
12
- export declare function voidSchema(): ParamSchema;
13
- export declare function anySchema(): ParamSchema;
14
- export declare function injectableSchema(name: string): ParamSchema;
15
- export declare function named(schema: ParamSchema, naming: string): ParamSchema;
16
- export declare function required(schema: ParamSchema): ParamSchema;
17
- export declare function requiredNotNull(schema: ParamSchema): ParamSchema;
18
- export declare function primitiveSchema(kind: 'void' | 'string' | 'number' | 'boolean' | 'function' | 'object' | 'symbol' | 'array'): ParamSchema;
19
- export declare function arrayOf(schema: ParamSchema): ParamSchema;
20
- export declare function objectOf(schema: ParamSchema): ParamSchema;
21
- export declare function oneOf<T extends readonly [string, ...string[]]>(values: T): ParamSchema;
22
- export declare function oneOfType(schemas: ParamSchema[]): ParamSchema;
23
- export declare function shape<T extends Record<string, ParamSchema>>(shapeMap: T): ParamSchema;
24
- export declare function instanceOf<T extends abstract new (...args: any[]) => any>(cls: T): ParamSchema;
25
- //# sourceMappingURL=primitives.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/schema/primitives.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EACH,MAAM,GACN,KAAK,GACL,OAAO,GACP,SAAS,GACT,UAAU,GACV,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,OAAO,GACP,WAAW,GACX,YAAY,GACZ,YAAY,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,mBAAmB,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAOD,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAEtD;AA8BD,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAInF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAMxD;AAED,wBAAgB,UAAU,IAAI,WAAW,CAIxC;AAED,wBAAgB,SAAS,IAAI,WAAW,CAIvC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAI1D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAKtE;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAKzD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAKhE;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAC1F,WAAW,CA8Bb;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAKxD;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAKzD;AAED,wBAAgB,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,WAAW,CAKtF;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,CAa7D;AAED,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,WAAW,CAOrF;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,WAAW,CAO9F"}