@yuhere/js-jsonrpc2 2.1.9 → 2.1.11
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/README.md +10 -2
- package/SKILL.md +21 -3
- package/dist/cli/cli.js +9 -1
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/demo-methods.d.ts.map +1 -1
- package/dist/cli/demo-methods.js +24 -25
- package/dist/cli/demo-methods.js.map +1 -1
- package/dist/core/Repository.d.ts +3 -7
- package/dist/core/Repository.d.ts.map +1 -1
- package/dist/core/Repository.js +159 -19
- package/dist/core/Repository.js.map +1 -1
- package/dist/core/descriptor.d.ts.map +1 -1
- package/dist/core/llm-tools.d.ts.map +1 -1
- package/dist/core/llm-tools.js +19 -14
- package/dist/core/llm-tools.js.map +1 -1
- package/dist/core/system-methods.d.ts.map +1 -1
- package/dist/core/system-methods.js +22 -6
- package/dist/core/system-methods.js.map +1 -1
- package/dist/metrics/memory.d.ts +59 -0
- package/dist/metrics/memory.d.ts.map +1 -0
- package/dist/metrics/memory.js +188 -0
- package/dist/metrics/memory.js.map +1 -0
- package/dist/metrics/prom.d.ts +1 -0
- package/dist/metrics/prom.d.ts.map +1 -0
- package/dist/metrics/prom.js +105 -0
- package/dist/metrics/prom.js.map +1 -0
- package/dist/schema/json/index.d.ts +1 -0
- package/dist/schema/json/index.d.ts.map +1 -1
- package/dist/schema/json/primitives.d.ts +81 -42
- package/dist/schema/json/primitives.d.ts.map +1 -1
- package/dist/schema/json/primitives.js +95 -67
- package/dist/schema/json/primitives.js.map +1 -1
- package/dist/schema/z/protocol.d.ts +1 -1
- package/dist/transport/express/middleware.d.ts +1 -1
- package/dist/transport/express/middleware.d.ts.map +1 -1
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/htdoc/assets/{index-BAZmvr5x.css → index-Ck-39Igh.css} +221 -0
- package/htdoc/assets/{index-sVQlhxjI.js → index-Cr0Jnrgb.js} +716 -35
- package/htdoc/assets/index-Cr0Jnrgb.js.map +1 -0
- package/htdoc/index.html +2 -2
- package/package.json +3 -3
- package/webui/src/App.tsx +101 -20
- package/webui/src/api/glob.ts +90 -0
- package/webui/src/api/metrics.ts +135 -0
- package/webui/src/api/paramForm.ts +4 -3
- package/webui/src/components/MetricsPanel.md +126 -0
- package/webui/src/components/MetricsPanel.tsx +290 -0
- package/webui/src/components/SchemaForm.tsx +29 -27
- package/webui/src/components/SchemaView.tsx +3 -3
- package/webui/src/hooks/useMetrics.ts +91 -0
- package/webui/src/styles/geek.css +221 -0
- package/htdoc/assets/index-sVQlhxjI.js.map +0 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 内存版 RPCMetrics。
|
|
3
|
+
*
|
|
4
|
+
* 按 method 聚合:调用次数、错误次数(按 code)、耗时直方图(固定桶)、
|
|
5
|
+
* 流式生命周期计数、首帧延迟直方图。
|
|
6
|
+
*
|
|
7
|
+
* 适合开发、测试、单机小服务;不持久化、不跨进程。
|
|
8
|
+
*/
|
|
9
|
+
const DURATION_BUCKETS = [
|
|
10
|
+
0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30,
|
|
11
|
+
];
|
|
12
|
+
const STREAM_DURATION_BUCKETS = [
|
|
13
|
+
0.1, 0.5, 1, 5, 10, 30, 60, 300, 1800,
|
|
14
|
+
];
|
|
15
|
+
const TTFB_BUCKETS = [
|
|
16
|
+
0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5,
|
|
17
|
+
];
|
|
18
|
+
function createHistogram(bounds) {
|
|
19
|
+
return {
|
|
20
|
+
count: 0,
|
|
21
|
+
sum: 0,
|
|
22
|
+
min: Number.POSITIVE_INFINITY,
|
|
23
|
+
max: Number.NEGATIVE_INFINITY,
|
|
24
|
+
bucketCounts: new Array(bounds.length + 1).fill(0),
|
|
25
|
+
bounds,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function observeHistogram(h, value) {
|
|
29
|
+
h.count += 1;
|
|
30
|
+
h.sum += value;
|
|
31
|
+
if (value < h.min)
|
|
32
|
+
h.min = value;
|
|
33
|
+
if (value > h.max)
|
|
34
|
+
h.max = value;
|
|
35
|
+
// 找到第一个 bounds[i] >= value 的桶;否则落入 +Inf 桶
|
|
36
|
+
let idx = h.bounds.length;
|
|
37
|
+
for (let i = 0; i < h.bounds.length; i++) {
|
|
38
|
+
if (value <= h.bounds[i]) {
|
|
39
|
+
idx = i;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
h.bucketCounts[idx] += 1;
|
|
44
|
+
}
|
|
45
|
+
function snapshotHistogram(h) {
|
|
46
|
+
const buckets = [];
|
|
47
|
+
let cumulative = 0;
|
|
48
|
+
for (let i = 0; i < h.bounds.length; i++) {
|
|
49
|
+
cumulative += h.bucketCounts[i];
|
|
50
|
+
buckets.push({ le: h.bounds[i], count: cumulative });
|
|
51
|
+
}
|
|
52
|
+
cumulative += h.bucketCounts[h.bounds.length];
|
|
53
|
+
buckets.push({ le: Number.POSITIVE_INFINITY, count: cumulative });
|
|
54
|
+
return {
|
|
55
|
+
count: h.count,
|
|
56
|
+
sum: h.sum,
|
|
57
|
+
min: h.count === 0 ? 0 : h.min,
|
|
58
|
+
max: h.count === 0 ? 0 : h.max,
|
|
59
|
+
buckets,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function createMethodState() {
|
|
63
|
+
return {
|
|
64
|
+
calls: 0,
|
|
65
|
+
callsByStatus: new Map(),
|
|
66
|
+
errorsByCode: new Map(),
|
|
67
|
+
duration: createHistogram(DURATION_BUCKETS),
|
|
68
|
+
streams: {
|
|
69
|
+
opened: 0,
|
|
70
|
+
completed: 0,
|
|
71
|
+
failed: 0,
|
|
72
|
+
failedByPhase: new Map(),
|
|
73
|
+
aborted: 0,
|
|
74
|
+
chunksTotal: 0,
|
|
75
|
+
duration: createHistogram(STREAM_DURATION_BUCKETS),
|
|
76
|
+
ttfb: createHistogram(TTFB_BUCKETS),
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function bump(map, key) {
|
|
81
|
+
map.set(key, (map.get(key) ?? 0) + 1);
|
|
82
|
+
}
|
|
83
|
+
export function createMemoryMetrics(options = {}) {
|
|
84
|
+
const normalize = options.normalizeMethod ?? ((m) => m);
|
|
85
|
+
const startedAt = Date.now();
|
|
86
|
+
const methods = new Map();
|
|
87
|
+
let invalidRequests = 0;
|
|
88
|
+
function stateOf(method) {
|
|
89
|
+
const key = normalize(method);
|
|
90
|
+
let state = methods.get(key);
|
|
91
|
+
if (!state) {
|
|
92
|
+
state = createMethodState();
|
|
93
|
+
methods.set(key, state);
|
|
94
|
+
}
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
onCallStart({ method }) {
|
|
99
|
+
// 只用于未来扩展(如活跃调用数);当前不聚合。
|
|
100
|
+
// 显式空实现,保证和 Repository 的调用契约一致。
|
|
101
|
+
void method;
|
|
102
|
+
},
|
|
103
|
+
onCallEnd({ method, status, code, durationSeconds }) {
|
|
104
|
+
if (method === '<invalid>') {
|
|
105
|
+
invalidRequests += 1;
|
|
106
|
+
if (code !== undefined) {
|
|
107
|
+
// 无效请求的错误码仍记录在 invalidRequests 上,
|
|
108
|
+
// 不污染任何具体 method 的状态。
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const state = stateOf(method);
|
|
113
|
+
state.calls += 1;
|
|
114
|
+
bump(state.callsByStatus, status);
|
|
115
|
+
if (code !== undefined)
|
|
116
|
+
bump(state.errorsByCode, code);
|
|
117
|
+
// stream_opened / stream_error 不计入普通耗时分布:
|
|
118
|
+
// - stream_opened:这只是「流已打开」的耗时,不是调用耗时
|
|
119
|
+
// - stream_error:首帧失败,耗时由 onStreamEvent(failed) 记录
|
|
120
|
+
if (status === 'success' || status === 'error') {
|
|
121
|
+
observeHistogram(state.duration, durationSeconds);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
onStreamEvent({ method, event, phase, chunks, durationSeconds, timeToFirstChunkSeconds, }) {
|
|
125
|
+
if (method === '<invalid>')
|
|
126
|
+
return;
|
|
127
|
+
const state = stateOf(method);
|
|
128
|
+
switch (event) {
|
|
129
|
+
case 'opened':
|
|
130
|
+
state.streams.opened += 1;
|
|
131
|
+
return;
|
|
132
|
+
case 'completed':
|
|
133
|
+
state.streams.completed += 1;
|
|
134
|
+
state.streams.chunksTotal += chunks;
|
|
135
|
+
observeHistogram(state.streams.duration, durationSeconds);
|
|
136
|
+
if (timeToFirstChunkSeconds !== undefined) {
|
|
137
|
+
observeHistogram(state.streams.ttfb, timeToFirstChunkSeconds);
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
case 'failed':
|
|
141
|
+
state.streams.failed += 1;
|
|
142
|
+
bump(state.streams.failedByPhase, phase ?? 'unknown');
|
|
143
|
+
state.streams.chunksTotal += chunks;
|
|
144
|
+
observeHistogram(state.streams.duration, durationSeconds);
|
|
145
|
+
if (timeToFirstChunkSeconds !== undefined) {
|
|
146
|
+
observeHistogram(state.streams.ttfb, timeToFirstChunkSeconds);
|
|
147
|
+
}
|
|
148
|
+
return;
|
|
149
|
+
case 'aborted':
|
|
150
|
+
state.streams.aborted += 1;
|
|
151
|
+
state.streams.chunksTotal += chunks;
|
|
152
|
+
observeHistogram(state.streams.duration, durationSeconds);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
snapshot() {
|
|
157
|
+
const out = {};
|
|
158
|
+
for (const [method, state] of methods) {
|
|
159
|
+
out[method] = {
|
|
160
|
+
calls: state.calls,
|
|
161
|
+
callsByStatus: Object.fromEntries(state.callsByStatus),
|
|
162
|
+
errorsByCode: Object.fromEntries([...state.errorsByCode].map(([code, n]) => [String(code), n])),
|
|
163
|
+
duration: snapshotHistogram(state.duration),
|
|
164
|
+
streams: {
|
|
165
|
+
opened: state.streams.opened,
|
|
166
|
+
completed: state.streams.completed,
|
|
167
|
+
failed: state.streams.failed,
|
|
168
|
+
failedByPhase: Object.fromEntries(state.streams.failedByPhase),
|
|
169
|
+
aborted: state.streams.aborted,
|
|
170
|
+
},
|
|
171
|
+
streamDuration: snapshotHistogram(state.streams.duration),
|
|
172
|
+
streamTimeToFirstChunk: snapshotHistogram(state.streams.ttfb),
|
|
173
|
+
streamChunksTotal: state.streams.chunksTotal,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
uptimeMs: Date.now() - startedAt,
|
|
178
|
+
methods: out,
|
|
179
|
+
invalidRequests,
|
|
180
|
+
};
|
|
181
|
+
},
|
|
182
|
+
reset() {
|
|
183
|
+
methods.clear();
|
|
184
|
+
invalidRequests = 0;
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/metrics/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=prom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prom.d.ts","sourceRoot":"","sources":["../../src/metrics/prom.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { Counter, Histogram, Gauge } from 'prom-client';
|
|
3
|
+
// import type { RPCMetrics } from '../types';
|
|
4
|
+
// export function createPromMetrics(): RPCMetrics {
|
|
5
|
+
// const calls = new Counter({
|
|
6
|
+
// name: 'rpc_calls_total',
|
|
7
|
+
// help: 'Total RPC calls',
|
|
8
|
+
// labelNames: ['method', 'status'],
|
|
9
|
+
// });
|
|
10
|
+
// const errors = new Counter({
|
|
11
|
+
// name: 'rpc_errors_total',
|
|
12
|
+
// help: 'Total RPC errors by code',
|
|
13
|
+
// labelNames: ['method', 'code'],
|
|
14
|
+
// });
|
|
15
|
+
// const duration = new Histogram({
|
|
16
|
+
// name: 'rpc_duration_seconds',
|
|
17
|
+
// help: 'RPC call duration',
|
|
18
|
+
// labelNames: ['method', 'status'],
|
|
19
|
+
// buckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30],
|
|
20
|
+
// });
|
|
21
|
+
// const inflight = new Gauge({
|
|
22
|
+
// name: 'rpc_inflight',
|
|
23
|
+
// help: 'In-flight RPC calls',
|
|
24
|
+
// labelNames: ['method'],
|
|
25
|
+
// });
|
|
26
|
+
// const streamOpened = new Counter({
|
|
27
|
+
// name: 'rpc_stream_opened_total',
|
|
28
|
+
// help: 'Streams opened',
|
|
29
|
+
// labelNames: ['method'],
|
|
30
|
+
// });
|
|
31
|
+
// const streamCompleted = new Counter({
|
|
32
|
+
// name: 'rpc_stream_completed_total',
|
|
33
|
+
// help: 'Streams completed',
|
|
34
|
+
// labelNames: ['method'],
|
|
35
|
+
// });
|
|
36
|
+
// const streamFailed = new Counter({
|
|
37
|
+
// name: 'rpc_stream_failed_total',
|
|
38
|
+
// help: 'Streams failed',
|
|
39
|
+
// labelNames: ['method', 'phase'],
|
|
40
|
+
// });
|
|
41
|
+
// const streamAborted = new Counter({
|
|
42
|
+
// name: 'rpc_stream_aborted_total',
|
|
43
|
+
// help: 'Streams aborted by client',
|
|
44
|
+
// labelNames: ['method'],
|
|
45
|
+
// });
|
|
46
|
+
// const ttfb = new Histogram({
|
|
47
|
+
// name: 'rpc_stream_time_to_first_chunk_seconds',
|
|
48
|
+
// help: 'Time to first stream chunk',
|
|
49
|
+
// labelNames: ['method'],
|
|
50
|
+
// buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5],
|
|
51
|
+
// });
|
|
52
|
+
// const streamDuration = new Histogram({
|
|
53
|
+
// name: 'rpc_stream_duration_seconds',
|
|
54
|
+
// help: 'Total stream duration',
|
|
55
|
+
// labelNames: ['method'],
|
|
56
|
+
// buckets: [0.1, 0.5, 1, 5, 10, 30, 60, 300, 1800],
|
|
57
|
+
// });
|
|
58
|
+
// return {
|
|
59
|
+
// onCallStart({ method }) {
|
|
60
|
+
// inflight.inc({ method });
|
|
61
|
+
// },
|
|
62
|
+
// onCallEnd({ method, status, code, durationSeconds }) {
|
|
63
|
+
// if (status === 'stream_opened') {
|
|
64
|
+
// // 流已打开:只减 inflight;calls/duration 交给 onStreamEvent
|
|
65
|
+
// inflight.dec({ method });
|
|
66
|
+
// return;
|
|
67
|
+
// }
|
|
68
|
+
// if (status === 'stream_error') {
|
|
69
|
+
// // before_first_chunk 失败:不再减 inflight(stream_opened 已减)
|
|
70
|
+
// calls.inc({ method, status });
|
|
71
|
+
// if (code !== undefined) errors.inc({ method, code: String(code) });
|
|
72
|
+
// return;
|
|
73
|
+
// }
|
|
74
|
+
// inflight.dec({ method });
|
|
75
|
+
// calls.inc({ method, status });
|
|
76
|
+
// if (code !== undefined) errors.inc({ method, code: String(code) });
|
|
77
|
+
// duration.observe({ method, status }, durationSeconds);
|
|
78
|
+
// },
|
|
79
|
+
// onStreamEvent({ method, event, phase, chunks, durationSeconds, timeToFirstChunkSeconds }) {
|
|
80
|
+
// if (event === 'opened') {
|
|
81
|
+
// streamOpened.inc({ method });
|
|
82
|
+
// calls.inc({ method, status: 'stream' });
|
|
83
|
+
// return;
|
|
84
|
+
// }
|
|
85
|
+
// if (event === 'completed') {
|
|
86
|
+
// streamCompleted.inc({ method });
|
|
87
|
+
// streamDuration.observe({ method }, durationSeconds);
|
|
88
|
+
// if (timeToFirstChunkSeconds !== undefined) ttfb.observe({ method }, timeToFirstChunkSeconds);
|
|
89
|
+
// return;
|
|
90
|
+
// }
|
|
91
|
+
// if (event === 'failed') {
|
|
92
|
+
// streamFailed.inc({ method, phase: phase ?? 'unknown' });
|
|
93
|
+
// streamDuration.observe({ method }, durationSeconds);
|
|
94
|
+
// if (timeToFirstChunkSeconds !== undefined) ttfb.observe({ method }, timeToFirstChunkSeconds);
|
|
95
|
+
// return;
|
|
96
|
+
// }
|
|
97
|
+
// if (event === 'aborted') {
|
|
98
|
+
// streamAborted.inc({ method });
|
|
99
|
+
// streamDuration.observe({ method }, durationSeconds);
|
|
100
|
+
// return;
|
|
101
|
+
// }
|
|
102
|
+
// },
|
|
103
|
+
// };
|
|
104
|
+
// }
|
|
105
|
+
//# sourceMappingURL=prom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prom.js","sourceRoot":"","sources":["../../src/metrics/prom.ts"],"names":[],"mappings":";AAAA,2DAA2D;AAC3D,8CAA8C;AAE9C,oDAAoD;AACpD,kCAAkC;AAClC,mCAAmC;AACnC,mCAAmC;AACnC,4CAA4C;AAC5C,UAAU;AACV,mCAAmC;AACnC,oCAAoC;AACpC,4CAA4C;AAC5C,0CAA0C;AAC1C,UAAU;AACV,uCAAuC;AACvC,wCAAwC;AACxC,qCAAqC;AACrC,4CAA4C;AAC5C,yFAAyF;AACzF,UAAU;AACV,mCAAmC;AACnC,gCAAgC;AAChC,uCAAuC;AACvC,kCAAkC;AAClC,UAAU;AACV,yCAAyC;AACzC,2CAA2C;AAC3C,kCAAkC;AAClC,kCAAkC;AAClC,UAAU;AACV,4CAA4C;AAC5C,8CAA8C;AAC9C,qCAAqC;AACrC,kCAAkC;AAClC,UAAU;AACV,yCAAyC;AACzC,2CAA2C;AAC3C,kCAAkC;AAClC,2CAA2C;AAC3C,UAAU;AACV,0CAA0C;AAC1C,4CAA4C;AAC5C,6CAA6C;AAC7C,kCAAkC;AAClC,UAAU;AACV,mCAAmC;AACnC,0DAA0D;AAC1D,8CAA8C;AAC9C,kCAAkC;AAClC,+DAA+D;AAC/D,UAAU;AACV,6CAA6C;AAC7C,+CAA+C;AAC/C,yCAAyC;AACzC,kCAAkC;AAClC,4DAA4D;AAC5D,UAAU;AAEV,eAAe;AACf,oCAAoC;AACpC,wCAAwC;AACxC,aAAa;AACb,iEAAiE;AACjE,gDAAgD;AAChD,sEAAsE;AACtE,4CAA4C;AAC5C,0BAA0B;AAC1B,gBAAgB;AAChB,+CAA+C;AAC/C,0EAA0E;AAC1E,iDAAiD;AACjD,sFAAsF;AACtF,0BAA0B;AAC1B,gBAAgB;AAChB,wCAAwC;AACxC,6CAA6C;AAC7C,kFAAkF;AAClF,qEAAqE;AACrE,aAAa;AACb,sGAAsG;AACtG,wCAAwC;AACxC,gDAAgD;AAChD,2DAA2D;AAC3D,0BAA0B;AAC1B,gBAAgB;AAChB,2CAA2C;AAC3C,mDAAmD;AACnD,uEAAuE;AACvE,gHAAgH;AAChH,0BAA0B;AAC1B,gBAAgB;AAChB,wCAAwC;AACxC,2EAA2E;AAC3E,uEAAuE;AACvE,gHAAgH;AAChH,0BAA0B;AAC1B,gBAAgB;AAChB,yCAAyC;AACzC,iDAAiD;AACjD,uEAAuE;AACvE,0BAA0B;AAC1B,gBAAgB;AAChB,aAAa;AACb,SAAS;AACT,IAAI"}
|
|
@@ -12,6 +12,7 @@ export declare const s: {
|
|
|
12
12
|
tuple: <const S extends readonly [import("./primitives.js").Schema<unknown>, ...import("./primitives.js").Schema<unknown>[]]>(schemas: S) => import("./primitives.js").TupleSchema<S>;
|
|
13
13
|
enum: <const T extends readonly [string, ...string[]]>(values: T) => import("./primitives.js").EnumSchema<T>;
|
|
14
14
|
unknown: () => import("./primitives.js").UnknownSchema;
|
|
15
|
+
null: () => import("./primitives.js").NullSchema;
|
|
15
16
|
void: () => import("./marker.js").VoidMarker;
|
|
16
17
|
injectable: <const K extends string>(key: K) => import("./marker.js").InjectableMarker<K>;
|
|
17
18
|
stream: <T>(inner: import("./primitives.js").Schema<T>) => import("./marker.js").StreamMarker<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/schema/json/index.ts"],"names":[],"mappings":"AAGA,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AAEzB,eAAO,MAAM,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/schema/json/index.ts"],"names":[],"mappings":"AAGA,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AAEzB,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;CAAgC,CAAC"}
|
|
@@ -12,6 +12,13 @@ export type SchemaKind = string;
|
|
|
12
12
|
export interface SchemaDescription {
|
|
13
13
|
kind: SchemaKind;
|
|
14
14
|
description?: string;
|
|
15
|
+
/**
|
|
16
|
+
* 该值是否允许为 null。
|
|
17
|
+
*
|
|
18
|
+
* 唯一真相来源:由 `NullableSchema` 及其子类通过 `.nullable(bool)` 设置,
|
|
19
|
+
* `UnknownSchema` / `NullSchema` 不使用该字段(它们本身就接受 null)。
|
|
20
|
+
* `kind` 永远表示值的真实形状,不会被 nullability 污染。
|
|
21
|
+
*/
|
|
15
22
|
nullable?: boolean;
|
|
16
23
|
constraints?: Record<string, unknown>;
|
|
17
24
|
children?: Record<string, unknown>;
|
|
@@ -21,10 +28,11 @@ export declare class SchemaValidationError extends Error {
|
|
|
21
28
|
constructor(message: string, path?: string[]);
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
|
-
* 所有 Schema
|
|
31
|
+
* 所有 Schema 的抽象基类。
|
|
25
32
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
33
|
+
* 只负责 description 与描述输出;nullability 由 `NullableSchema` 提供。
|
|
34
|
+
* `UnknownSchema` / `NullSchema` 直接继承本类——它们天然接受 null,
|
|
35
|
+
* 不需要 `.nullable()`。
|
|
28
36
|
*/
|
|
29
37
|
export declare abstract class Schema<T> {
|
|
30
38
|
abstract readonly kind: SchemaKind;
|
|
@@ -33,7 +41,6 @@ export declare abstract class Schema<T> {
|
|
|
33
41
|
describe(description: string): this;
|
|
34
42
|
/**
|
|
35
43
|
* 创建保留原型和现有字段的新实例,供不可变链式方法使用。
|
|
36
|
-
* Schema 子类的状态字段会一并复制,因此扩展类仍保留自身原型和状态。
|
|
37
44
|
*/
|
|
38
45
|
protected cloneWith(updates: Record<string, unknown>): this;
|
|
39
46
|
getDescription(): string | undefined;
|
|
@@ -51,62 +58,67 @@ export declare abstract class Schema<T> {
|
|
|
51
58
|
protected fail(message: string, path: string[]): never;
|
|
52
59
|
}
|
|
53
60
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* nullable 包装器。
|
|
61
|
+
* 支持 nullability 的 Schema 基类。
|
|
62
|
+
*
|
|
63
|
+
* 除 `UnknownSchema` / `NullSchema` 外的所有具体 Schema 都继承本类。
|
|
64
|
+
*
|
|
65
|
+
* - `nullable()` / `nullable(true)` → 允许 null
|
|
66
|
+
* - `nullable(false)` → 不允许 null(撤销之前的标记)
|
|
62
67
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
68
|
+
* `_parse` 在调用子类 `_parseValue` 前统一做 null 短路;
|
|
69
|
+
* `toJSON()` 在基类输出上附加 `nullable: true`。
|
|
65
70
|
*/
|
|
66
|
-
export declare class NullableSchema<T> extends Schema<T | null> {
|
|
67
|
-
private
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
export declare abstract class NullableSchema<T> extends Schema<T | null> {
|
|
72
|
+
private _nullable;
|
|
73
|
+
nullable(value?: boolean): this;
|
|
74
|
+
isNullable(): boolean;
|
|
70
75
|
protected _parse(input: unknown, path: string[]): T | null;
|
|
71
|
-
protected
|
|
76
|
+
protected abstract _parseValue(input: unknown, path: string[]): T;
|
|
77
|
+
toJSON(): SchemaDescription;
|
|
72
78
|
}
|
|
73
|
-
export declare class StringSchema<K extends string = "string"> extends
|
|
79
|
+
export declare class StringSchema<K extends string = "string"> extends NullableSchema<string> {
|
|
74
80
|
readonly kind: K;
|
|
75
81
|
constructor();
|
|
76
82
|
private minimum?;
|
|
77
83
|
private maximum?;
|
|
78
84
|
min(value: number): this;
|
|
79
85
|
max(value: number): this;
|
|
80
|
-
protected
|
|
86
|
+
protected _parseValue(input: unknown, path: string[]): string;
|
|
81
87
|
protected _describe(): SchemaDescription;
|
|
82
88
|
protected validateBound(value: number): void;
|
|
83
89
|
}
|
|
84
|
-
export declare class NumberSchema extends
|
|
90
|
+
export declare class NumberSchema extends NullableSchema<number> {
|
|
85
91
|
readonly kind: "number";
|
|
86
92
|
constructor();
|
|
87
93
|
private minimum?;
|
|
88
94
|
private maximum?;
|
|
89
95
|
min(value: number): this;
|
|
90
96
|
max(value: number): this;
|
|
91
|
-
protected
|
|
97
|
+
protected _parseValue(input: unknown, path: string[]): number;
|
|
92
98
|
protected _describe(): SchemaDescription;
|
|
93
99
|
protected validateBound(value: number): void;
|
|
94
100
|
}
|
|
95
|
-
export declare class BooleanSchema extends
|
|
101
|
+
export declare class BooleanSchema extends NullableSchema<boolean> {
|
|
96
102
|
readonly kind: "boolean";
|
|
97
103
|
constructor();
|
|
98
|
-
protected
|
|
104
|
+
protected _parseValue(input: unknown, path: string[]): boolean;
|
|
99
105
|
protected _describe(): SchemaDescription;
|
|
100
106
|
}
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
/**
|
|
108
|
+
* 字面量只支持 string / number / boolean。
|
|
109
|
+
*
|
|
110
|
+
* null 由 `s.null()` 表达;需要「该字面量或 null」时,对字面量调用
|
|
111
|
+
* `.nullable()`。`literal(null)` 会抛 TypeError。
|
|
112
|
+
*/
|
|
113
|
+
export type LiteralValue = string | number | boolean;
|
|
114
|
+
export declare class LiteralSchema<const T extends LiteralValue> extends NullableSchema<T> {
|
|
103
115
|
private readonly expected;
|
|
104
116
|
readonly kind: "literal";
|
|
105
117
|
constructor(expected: T);
|
|
106
|
-
protected
|
|
118
|
+
protected _parseValue(input: unknown, path: string[]): T;
|
|
107
119
|
protected _describe(): SchemaDescription;
|
|
108
120
|
}
|
|
109
|
-
export declare class ArraySchema<T> extends
|
|
121
|
+
export declare class ArraySchema<T> extends NullableSchema<T[]> {
|
|
110
122
|
private readonly itemSchema;
|
|
111
123
|
readonly kind: "array";
|
|
112
124
|
private minimum?;
|
|
@@ -114,7 +126,7 @@ export declare class ArraySchema<T> extends NullableCapableSchema<T[]> {
|
|
|
114
126
|
constructor(itemSchema: Schema<T>);
|
|
115
127
|
min(value: number): this;
|
|
116
128
|
max(value: number): this;
|
|
117
|
-
protected
|
|
129
|
+
protected _parseValue(input: unknown, path: string[]): T[];
|
|
118
130
|
protected _describe(): SchemaDescription;
|
|
119
131
|
protected validateBound(value: number): void;
|
|
120
132
|
}
|
|
@@ -126,7 +138,7 @@ type ShapeOutput<S extends ObjectShape> = {
|
|
|
126
138
|
type OptionalShapeOutput<S extends ObjectShape> = {
|
|
127
139
|
[K in keyof S]?: SchemaValue<S[K]>;
|
|
128
140
|
};
|
|
129
|
-
export declare class ObjectSchema<S extends ObjectShape, Strict extends boolean = false> extends
|
|
141
|
+
export declare class ObjectSchema<S extends ObjectShape, Strict extends boolean = false> extends NullableSchema<Strict extends true ? ShapeOutput<S> : OptionalShapeOutput<S>> {
|
|
130
142
|
private readonly shape;
|
|
131
143
|
readonly kind: "object";
|
|
132
144
|
private isStrict;
|
|
@@ -135,10 +147,10 @@ export declare class ObjectSchema<S extends ObjectShape, Strict extends boolean
|
|
|
135
147
|
* strict() 要求所有声明属性存在,并拒绝未声明属性。
|
|
136
148
|
*/
|
|
137
149
|
strict(): ObjectSchema<S, true>;
|
|
138
|
-
protected
|
|
150
|
+
protected _parseValue(input: unknown, path: string[]): Strict extends true ? ShapeOutput<S> : OptionalShapeOutput<S>;
|
|
139
151
|
protected _describe(): SchemaDescription;
|
|
140
152
|
}
|
|
141
|
-
export declare class RecordSchema<T> extends
|
|
153
|
+
export declare class RecordSchema<T> extends NullableSchema<Record<string, T>> {
|
|
142
154
|
private readonly valueSchema;
|
|
143
155
|
readonly kind: "record";
|
|
144
156
|
private minimum?;
|
|
@@ -146,37 +158,51 @@ export declare class RecordSchema<T> extends NullableCapableSchema<Record<string
|
|
|
146
158
|
constructor(valueSchema: Schema<T>);
|
|
147
159
|
min(value: number): this;
|
|
148
160
|
max(value: number): this;
|
|
149
|
-
protected
|
|
161
|
+
protected _parseValue(input: unknown, path: string[]): Record<string, T>;
|
|
150
162
|
protected _describe(): SchemaDescription;
|
|
151
163
|
protected validateBound(value: number): void;
|
|
152
164
|
}
|
|
153
|
-
|
|
154
|
-
|
|
165
|
+
/**
|
|
166
|
+
* 联合。
|
|
167
|
+
*
|
|
168
|
+
* 传入的 member schemas 会被 clone 并 `nullable(false)`——因为「某个
|
|
169
|
+
* 分支允许 null」这件事在 union 层面没有意义:null 是否允许应通过
|
|
170
|
+
* `union(...).nullable()` 统一表达。
|
|
171
|
+
*/
|
|
172
|
+
export declare class UnionSchema<const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]> extends NullableSchema<SchemaValue<S[number]>> {
|
|
155
173
|
readonly kind: "union";
|
|
174
|
+
private readonly options;
|
|
156
175
|
constructor(schemas: S);
|
|
157
|
-
protected
|
|
176
|
+
protected _parseValue(input: unknown, path: string[]): SchemaValue<S[number]>;
|
|
158
177
|
protected _describe(): SchemaDescription;
|
|
159
178
|
}
|
|
160
|
-
export declare class TupleSchema<const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]> extends
|
|
179
|
+
export declare class TupleSchema<const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]> extends NullableSchema<SchemaValue<S[number]>[]> {
|
|
161
180
|
private readonly schemas;
|
|
162
181
|
readonly kind: "tuple";
|
|
163
182
|
constructor(schemas: S);
|
|
164
|
-
protected
|
|
183
|
+
protected _parseValue(input: unknown, path: string[]): SchemaValue<S[number]>[];
|
|
165
184
|
protected _describe(): SchemaDescription;
|
|
166
185
|
}
|
|
167
|
-
|
|
186
|
+
/**
|
|
187
|
+
* 字符串枚举。
|
|
188
|
+
*
|
|
189
|
+
* 继承 `NullableSchema`,因此可以 `s.enum([...]).nullable()`;
|
|
190
|
+
* 它不包含嵌套 schema,所以不需要像 union 那样处理成员 nullability。
|
|
191
|
+
*/
|
|
192
|
+
export declare class EnumSchema<const T extends readonly [string, ...string[]]> extends NullableSchema<T[number]> {
|
|
168
193
|
private readonly values;
|
|
169
194
|
readonly kind: "enum";
|
|
170
195
|
private readonly allowedValues;
|
|
171
196
|
constructor(values: T);
|
|
172
|
-
protected
|
|
197
|
+
protected _parseValue(input: unknown, path: string[]): T[number];
|
|
173
198
|
protected _describe(): SchemaDescription;
|
|
174
199
|
}
|
|
175
200
|
/**
|
|
176
201
|
* 校验任意 JSON 值。
|
|
177
202
|
*
|
|
178
203
|
* 不允许 undefined、非有限数字、循环引用等非 JSON 数据。
|
|
179
|
-
*
|
|
204
|
+
* null 本身就在接受范围内,因此不继承 `NullableSchema`,也不提供
|
|
205
|
+
* `.nullable()`——那是冗余的。
|
|
180
206
|
*/
|
|
181
207
|
export declare class UnknownSchema extends Schema<JSONValue> {
|
|
182
208
|
readonly kind: "unknown";
|
|
@@ -184,6 +210,18 @@ export declare class UnknownSchema extends Schema<JSONValue> {
|
|
|
184
210
|
protected _parse(input: unknown, path: string[]): JSONValue;
|
|
185
211
|
protected _describe(): SchemaDescription;
|
|
186
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* 精确的 null 值。
|
|
215
|
+
*
|
|
216
|
+
* 与 `UnknownSchema` 一样天然表达 null,不需要 `.nullable()`。
|
|
217
|
+
* 想表达「某类型或 null」用 `.nullable()`;想表达「就是 null」用 `s.null()`。
|
|
218
|
+
*/
|
|
219
|
+
export declare class NullSchema extends Schema<null> {
|
|
220
|
+
readonly kind: "null";
|
|
221
|
+
constructor();
|
|
222
|
+
protected _parse(input: unknown, path: string[]): null;
|
|
223
|
+
protected _describe(): SchemaDescription;
|
|
224
|
+
}
|
|
187
225
|
export type Infer<T extends Schema<unknown>> = T extends Schema<infer U> ? U : never;
|
|
188
226
|
export declare const primitives: {
|
|
189
227
|
string: () => StringSchema<"string">;
|
|
@@ -197,6 +235,7 @@ export declare const primitives: {
|
|
|
197
235
|
tuple: <const S extends readonly [Schema<unknown>, ...Schema<unknown>[]]>(schemas: S) => TupleSchema<S>;
|
|
198
236
|
enum: <const T extends readonly [string, ...string[]]>(values: T) => EnumSchema<T>;
|
|
199
237
|
unknown: () => UnknownSchema;
|
|
238
|
+
null: () => NullSchema;
|
|
200
239
|
};
|
|
201
240
|
export {};
|
|
202
241
|
//# sourceMappingURL=primitives.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/schema/json/primitives.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE7D,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAEhC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,IAAI,EAAE,MAAM,EAAE;IAFhC,YACE,OAAO,EAAE,MAAM,EACC,IAAI,GAAE,MAAM,EAAO,EAIpC;CACF;AAED
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/schema/json/primitives.ts"],"names":[],"mappings":"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"}
|