@svadmin/surface 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/compatibility.json +1 -1
- package/dist/agent-text.d.ts +27 -0
- package/dist/agent-text.js +94 -0
- package/dist/agent.d.ts +7 -1
- package/dist/agent.js +6 -2
- package/dist/components/SurfaceRenderer.svelte +16 -14
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/localization.d.ts +1 -0
- package/dist/localization.js +2 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -119,6 +119,31 @@ if (response.ok && response.value.action === 'propose') {
|
|
|
119
119
|
|
|
120
120
|
Use the same task-scoped catalog for generation, validation and rendering. JSON Schema narrows generation but does not replace cross-source binding checks, field policy or server authorization. The schema is not claimed to match every vendor's restricted structured-output subset.
|
|
121
121
|
|
|
122
|
+
### Inline chat answers
|
|
123
|
+
|
|
124
|
+
A chat host can answer with prose plus one inline card instead of a JSON-only reply. Pass `{ presentation: 'chat' }`, then split the streamed answer with `splitSurfaceAgentText()`:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import {
|
|
128
|
+
SURFACE_AGENT_FENCE_TAG,
|
|
129
|
+
buildSurfaceAgentMessages,
|
|
130
|
+
parseSurfaceAgentResponse,
|
|
131
|
+
splitSurfaceAgentText,
|
|
132
|
+
} from '@svadmin/surface';
|
|
133
|
+
|
|
134
|
+
const messages = buildSurfaceAgentMessages(request, catalog, policy, { presentation: 'chat' });
|
|
135
|
+
// 边生成边切分;未闭合的 surface 围栏返回 complete: false。
|
|
136
|
+
for (const segment of splitSurfaceAgentText(streamedText, { streaming: true })) {
|
|
137
|
+
if (segment.kind === 'text') renderMarkdown(segment.text);
|
|
138
|
+
else if (segment.complete) {
|
|
139
|
+
const parsed = parseSurfaceAgentResponse(segment.json, catalog, policy);
|
|
140
|
+
if (parsed.ok && parsed.value.action === 'propose') renderPreview(parsed.value.spec);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Only fences tagged `surface` (```` ```surface ````) are treated as proposals; every other fence stays in the prose, so ordinary JSON or shell snippets are never mistaken for a card. An unterminated fence becomes an incomplete segment only while `streaming` is true, which keeps partial JSON out of the renderer while the answer is still generating. Segmentation is presentation only: it does not validate, query data, render, or replace the host approval step.
|
|
146
|
+
|
|
122
147
|
`buildSurfaceAgentPrompt()` and `parseSurfaceAgentProposal()` remain compatible with the legacy proposal-only `surface-agent/v1` envelope. The new message API uses `surface-agent/v2` with a structured `cannot-fulfill` alternative. `createSurfaceAgentStream()` buffers bounded text and validates at `finish()`; it does **not** render partial JSON or implement OpenUI Lang streaming.
|
|
123
148
|
|
|
124
149
|
## Revisioned edits and explicit preview
|
package/compatibility.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** 聊天回答里标记界面提案的围栏标签,例如 ```surface。 */
|
|
2
|
+
export declare const SURFACE_AGENT_FENCE_TAG = "surface";
|
|
3
|
+
/** 聊天回答切分后的片段:普通正文,或一段待校验的界面提案 JSON。 */
|
|
4
|
+
export type SurfaceAgentTextSegment = {
|
|
5
|
+
readonly kind: 'text';
|
|
6
|
+
readonly text: string;
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'proposal';
|
|
9
|
+
readonly json: string;
|
|
10
|
+
readonly complete: boolean;
|
|
11
|
+
};
|
|
12
|
+
export interface SurfaceAgentTextOptions {
|
|
13
|
+
/** 生成尚未结束时,未闭合的 surface 围栏作为未完成提案返回。 */
|
|
14
|
+
readonly streaming?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 把聊天回答切成正文与界面提案,供宿主内联渲染。
|
|
18
|
+
*
|
|
19
|
+
* 只识别 `surface` 标签的围栏;其它围栏(例如 json 代码块)原样留在正文里,
|
|
20
|
+
* 避免把普通代码误当成界面提案。片段内容不做校验,宿主仍需按 catalog 和
|
|
21
|
+
* policy 调用 `parseSurfaceAgentResponse()` 或 `parseSurfaceAgentProposal()`。
|
|
22
|
+
*
|
|
23
|
+
* @param text 模型输出的完整或增量文本。
|
|
24
|
+
* @param options 生成中时传入 `streaming: true`,未闭合围栏按未完成提案返回。
|
|
25
|
+
* @returns 按出现顺序排列的片段;正文与提案互不重叠,围栏行不出现在正文里。
|
|
26
|
+
*/
|
|
27
|
+
export declare function splitSurfaceAgentText(text: string, options?: SurfaceAgentTextOptions): readonly SurfaceAgentTextSegment[];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { SURFACE_AGENT_LIMITS } from './agent-contract.js';
|
|
2
|
+
/** 聊天回答里标记界面提案的围栏标签,例如 ```surface。 */
|
|
3
|
+
export const SURFACE_AGENT_FENCE_TAG = 'surface';
|
|
4
|
+
const OPEN_FENCE = /^ {0,3}(`{3,}|~{3,})[ \t]*([^\s`]*)[^`]*$/u;
|
|
5
|
+
const CLOSE_FENCE = /^ {0,3}(`{3,}|~{3,})[ \t]*$/u;
|
|
6
|
+
function openingFence(line) {
|
|
7
|
+
const match = OPEN_FENCE.exec(line);
|
|
8
|
+
if (!match?.[1])
|
|
9
|
+
return undefined;
|
|
10
|
+
return { marker: match[1], tag: (match[2] ?? '').toLowerCase(), line };
|
|
11
|
+
}
|
|
12
|
+
function closesFence(line, fence) {
|
|
13
|
+
const match = CLOSE_FENCE.exec(line);
|
|
14
|
+
if (!match?.[1])
|
|
15
|
+
return false;
|
|
16
|
+
return match[1][0] === fence.marker[0] && match[1].length >= fence.marker.length;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 把聊天回答切成正文与界面提案,供宿主内联渲染。
|
|
20
|
+
*
|
|
21
|
+
* 只识别 `surface` 标签的围栏;其它围栏(例如 json 代码块)原样留在正文里,
|
|
22
|
+
* 避免把普通代码误当成界面提案。片段内容不做校验,宿主仍需按 catalog 和
|
|
23
|
+
* policy 调用 `parseSurfaceAgentResponse()` 或 `parseSurfaceAgentProposal()`。
|
|
24
|
+
*
|
|
25
|
+
* @param text 模型输出的完整或增量文本。
|
|
26
|
+
* @param options 生成中时传入 `streaming: true`,未闭合围栏按未完成提案返回。
|
|
27
|
+
* @returns 按出现顺序排列的片段;正文与提案互不重叠,围栏行不出现在正文里。
|
|
28
|
+
*/
|
|
29
|
+
export function splitSurfaceAgentText(text, options = {}) {
|
|
30
|
+
if (typeof text !== 'string' || text.length === 0)
|
|
31
|
+
return [];
|
|
32
|
+
// 超长输入按上限截断扫描,其余内容作为正文交还宿主,避免无界遍历。
|
|
33
|
+
const bounded = text.slice(0, SURFACE_AGENT_LIMITS.maxInputCharacters);
|
|
34
|
+
const overflow = text.slice(bounded.length);
|
|
35
|
+
const segments = [];
|
|
36
|
+
let prose = [];
|
|
37
|
+
let fence;
|
|
38
|
+
let proposal;
|
|
39
|
+
const flushProse = () => {
|
|
40
|
+
const value = prose.join('\n');
|
|
41
|
+
prose = [];
|
|
42
|
+
if (value === '')
|
|
43
|
+
return;
|
|
44
|
+
segments.push({ kind: 'text', text: value });
|
|
45
|
+
};
|
|
46
|
+
const flushProposal = (complete) => {
|
|
47
|
+
if (proposal === undefined || fence === undefined)
|
|
48
|
+
return;
|
|
49
|
+
flushProse();
|
|
50
|
+
segments.push({ kind: 'proposal', json: proposal.join('\n').trim(), complete });
|
|
51
|
+
proposal = undefined;
|
|
52
|
+
fence = undefined;
|
|
53
|
+
};
|
|
54
|
+
for (const line of bounded.split(/\r?\n/u)) {
|
|
55
|
+
if (proposal !== undefined && fence !== undefined) {
|
|
56
|
+
if (closesFence(line, fence))
|
|
57
|
+
flushProposal(true);
|
|
58
|
+
else
|
|
59
|
+
proposal.push(line);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (fence !== undefined) {
|
|
63
|
+
// 其它围栏内的内容原样保留,围栏内的 surface 字样不是提案。
|
|
64
|
+
prose.push(line);
|
|
65
|
+
if (closesFence(line, fence))
|
|
66
|
+
fence = undefined;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const open = openingFence(line);
|
|
70
|
+
if (open === undefined) {
|
|
71
|
+
prose.push(line);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
fence = open;
|
|
75
|
+
if (open.tag === SURFACE_AGENT_FENCE_TAG)
|
|
76
|
+
proposal = [];
|
|
77
|
+
else
|
|
78
|
+
prose.push(line);
|
|
79
|
+
}
|
|
80
|
+
if (proposal !== undefined && fence !== undefined) {
|
|
81
|
+
if (options.streaming === true)
|
|
82
|
+
flushProposal(false);
|
|
83
|
+
else {
|
|
84
|
+
// 非流式输出里未闭合的围栏是残缺内容,交还正文而不是静默丢弃。
|
|
85
|
+
prose.push(fence.line, ...proposal);
|
|
86
|
+
fence = undefined;
|
|
87
|
+
proposal = undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
flushProse();
|
|
91
|
+
if (overflow.length > 0)
|
|
92
|
+
segments.push({ kind: 'text', text: overflow });
|
|
93
|
+
return segments;
|
|
94
|
+
}
|
package/dist/agent.d.ts
CHANGED
|
@@ -37,8 +37,14 @@ export declare function parseSurfaceAgentProposal(input: unknown, catalog: Surfa
|
|
|
37
37
|
export declare function parseSurfaceAgentResponse(input: unknown, catalog: SurfaceCatalog, policy: SurfacePolicy): SurfaceAgentResponseResult;
|
|
38
38
|
/** 兼容旧 v1 输出,同时补齐从组件契约派生的完整参数/结构 schema。 */
|
|
39
39
|
export declare function buildSurfaceAgentPrompt(request: string, catalog: SurfaceCatalog, policy: SurfacePolicy): string;
|
|
40
|
+
/** 模型回答的呈现方式:纯 JSON 信封,或聊天正文加一个内联界面提案。 */
|
|
41
|
+
export type SurfaceAgentPresentation = 'json' | 'chat';
|
|
42
|
+
export interface SurfaceAgentMessageOptions {
|
|
43
|
+
/** 默认 `json`,保持既有调用方的行为不变。 */
|
|
44
|
+
readonly presentation?: SurfaceAgentPresentation;
|
|
45
|
+
}
|
|
40
46
|
/** 系统契约与用户需求分开传递;不绑定某个模型厂商或 CSS 编译器。 */
|
|
41
|
-
export declare function buildSurfaceAgentMessages(request: string, catalog: SurfaceCatalog, policy: SurfacePolicy): readonly SurfaceAgentMessage[];
|
|
47
|
+
export declare function buildSurfaceAgentMessages(request: string, catalog: SurfaceCatalog, policy: SurfacePolicy, options?: SurfaceAgentMessageOptions): readonly SurfaceAgentMessage[];
|
|
42
48
|
export interface SurfaceAgentStream {
|
|
43
49
|
/** 接收文本,不解析、不渲染、不查询数据。 */
|
|
44
50
|
push(chunk: string): {
|
package/dist/agent.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Type } from 'typebox';
|
|
2
2
|
import { Compile } from 'typebox/compile';
|
|
3
3
|
import { SURFACE_AGENT_LIMITS, SURFACE_AGENT_RESPONSE_SCHEMA_VERSION, SURFACE_AGENT_SCHEMA_VERSION, createSurfaceAgentResponseSchema, createSurfaceCatalogManifest, createSurfaceGenerationSpecSchema, surfaceCannotFulfillSchema, surfaceSchemaToJson, } from './agent-contract.js';
|
|
4
|
+
import { SURFACE_AGENT_FENCE_TAG } from './agent-text.js';
|
|
4
5
|
import { validateSurfaceSpec, surfaceSchemaIssues } from './validation.js';
|
|
5
6
|
import { parseSurfaceJson, surfaceWireError } from './wire.js';
|
|
6
7
|
export { SURFACE_AGENT_SCHEMA_VERSION } from './agent-contract.js';
|
|
@@ -77,9 +78,12 @@ export function buildSurfaceAgentPrompt(request, catalog, policy) {
|
|
|
77
78
|
return boundedPrompt(`${request}\n\n[svadmin surface agent protocol]\nReturn only a human-reviewable fenced JSON proposal. ${safetyInstructions}\n${contractContext(catalog, policy)}\nOutput JSON Schema: ${JSON.stringify(schema)}\nIf the request cannot be represented safely, explain the limitation without inventing fields or capabilities. For machine-readable cannot-fulfill responses use the surface-agent/v2 message API.`);
|
|
78
79
|
}
|
|
79
80
|
/** 系统契约与用户需求分开传递;不绑定某个模型厂商或 CSS 编译器。 */
|
|
80
|
-
export function buildSurfaceAgentMessages(request, catalog, policy) {
|
|
81
|
+
export function buildSurfaceAgentMessages(request, catalog, policy, options = {}) {
|
|
81
82
|
validateRequest(request);
|
|
82
|
-
const
|
|
83
|
+
const schema = JSON.stringify(createSurfaceAgentResponseSchema(catalog, policy));
|
|
84
|
+
const content = options.presentation === 'chat'
|
|
85
|
+
? boundedPrompt(`[svadmin surface agent protocol]\nAnswer the user in short prose first, then embed exactly one interface proposal in a \`\`\`${SURFACE_AGENT_FENCE_TAG} fenced block matching the output schema. Emit at most one such block, do not add other fenced blocks, and do not repeat the JSON outside the fence. ${safetyInstructions}\n${contractContext(catalog, policy)}\nOutput JSON Schema: ${schema}\nIf the request cannot be represented, answer in prose and omit the fenced block; never invent capabilities or return an incomplete spec.`)
|
|
86
|
+
: boundedPrompt(`[svadmin surface agent protocol]\nReturn exactly one JSON object matching the output schema, without markdown or prose. ${safetyInstructions}\n${contractContext(catalog, policy)}\nOutput JSON Schema: ${schema}\nIf the request cannot be represented, return action "cannot-fulfill" with a reason and a short message. Never invent capabilities or return an incomplete spec.`);
|
|
83
87
|
return [{ role: 'system', content }, { role: 'user', content: request }];
|
|
84
88
|
}
|
|
85
89
|
/** 有界传输缓冲,不冒充 OpenUI 增量渲染;半成品不进入运行时。 */
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import type { SurfaceMessages } from '../localization.js';
|
|
12
12
|
import type {
|
|
13
13
|
SurfaceDataError, SurfaceDataProvider, SurfacePolicy,
|
|
14
|
-
SurfaceSourceDataState, SurfaceValidationIssue, JsonObject,
|
|
14
|
+
SurfaceSourceDataState, SurfaceValidationIssue, SurfaceWidgetDataState, JsonObject,
|
|
15
15
|
} from '../types.js';
|
|
16
16
|
import { validateSurfaceSpec } from '../validation.js';
|
|
17
17
|
import { createSurfaceSourceCache, sameSourceIdentity, snapshotSurfaceSource } from '../source-cache.js';
|
|
@@ -55,6 +55,18 @@
|
|
|
55
55
|
const i18n = useTranslation();
|
|
56
56
|
const activeLocale = $derived(locale ?? i18n.locale);
|
|
57
57
|
const activeMessages = $derived(resolveSurfaceMessages(activeLocale, messages));
|
|
58
|
+
// 统一呈现边界:错误状态只暴露本地化文案,宿主诊断仍留在 onError。
|
|
59
|
+
function presentSurfaceData(data: SurfaceWidgetDataState): SurfaceWidgetDataState {
|
|
60
|
+
if (data.status !== 'error') return data;
|
|
61
|
+
const message = data.error.code === 'access_denied'
|
|
62
|
+
? activeMessages.accessDenied
|
|
63
|
+
: data.error.code === 'provider_result_not_json' || data.error.code === 'binding_pointer_not_found'
|
|
64
|
+
? activeMessages.invalidData
|
|
65
|
+
: activeMessages.providerUnavailable;
|
|
66
|
+
return data.error.message === message
|
|
67
|
+
? data
|
|
68
|
+
: { ...data, error: { ...data.error, message } };
|
|
69
|
+
}
|
|
58
70
|
const validation = $derived(validateSurfaceSpec(spec, catalog, policy));
|
|
59
71
|
const widgetRegistrations = $derived(new Map(catalog.widgets.map((widget) => [widget.type, widget])));
|
|
60
72
|
const sourceStates = new SvelteMap<string, SurfaceSourceDataState>();
|
|
@@ -69,18 +81,8 @@
|
|
|
69
81
|
]);
|
|
70
82
|
// 复用 PR #428 的请求所有权与会话隔离实现,不维护第二套缓存。
|
|
71
83
|
const sourceCache = createSurfaceSourceCache({
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
sourceStates.set(id, state);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const message = state.error.code === 'access_denied'
|
|
78
|
-
? activeMessages.accessDenied
|
|
79
|
-
: state.error.code === 'provider_result_not_json' || state.error.code === 'binding_pointer_not_found'
|
|
80
|
-
? state.error.message
|
|
81
|
-
: activeMessages.providerUnavailable;
|
|
82
|
-
sourceStates.set(id, { ...state, error: { ...state.error, message } });
|
|
83
|
-
},
|
|
84
|
+
// 缓存只保存原始 source 状态;本地化等呈现规则统一在渲染边界执行。
|
|
85
|
+
set: (id, state) => { sourceStates.set(id, state); },
|
|
84
86
|
remove: (id) => { sourceStates.delete(id); },
|
|
85
87
|
onError: (state, diagnostic) => { onError?.({ type: 'data', error: diagnostic ?? state.error }); },
|
|
86
88
|
});
|
|
@@ -180,7 +182,7 @@
|
|
|
180
182
|
<div class="surface-widget surface-span-{widget.placement?.columnSpan ?? 12} {semantic ? appearanceClasses(widget.props) : ''}" data-testid="surface-widget-{widget.id}">
|
|
181
183
|
{#if WidgetComponent}
|
|
182
184
|
<WidgetComponent widgetId={widget.id} props={semantic ? withoutSurfaceAppearance(widget.props) : widget.props}
|
|
183
|
-
data={resolveSurfaceSourceData(widget, widget.binding ? sourceStates.get(widget.binding.sourceId) : undefined)}
|
|
185
|
+
data={presentSurfaceData(resolveSurfaceSourceData(widget, widget.binding ? sourceStates.get(widget.binding.sourceId) : undefined))}
|
|
184
186
|
locale={activeLocale} messages={activeMessages} />
|
|
185
187
|
{/if}
|
|
186
188
|
</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ export type { JsonObject, JsonPrimitive, JsonValue, ResourceListDataSource, Reso
|
|
|
3
3
|
export { validateSurfaceSpec } from './validation.js';
|
|
4
4
|
export type { SurfaceMessages } from './localization.js';
|
|
5
5
|
export { SURFACE_AGENT_SCHEMA_VERSION, buildSurfaceAgentPrompt, buildSurfaceAgentMessages, parseSurfaceAgentProposal, parseSurfaceAgentResponse, createSurfaceAgentStream, } from './agent.js';
|
|
6
|
+
export { SURFACE_AGENT_FENCE_TAG, splitSurfaceAgentText, } from './agent-text.js';
|
|
7
|
+
export type { SurfaceAgentTextSegment, SurfaceAgentTextOptions, } from './agent-text.js';
|
|
8
|
+
export type { SurfaceAgentMessageOptions, SurfaceAgentPresentation, } from './agent.js';
|
|
6
9
|
export type { SurfaceAgentProposal, SurfaceAgentProposalV2, SurfaceAgentCannotFulfill, SurfaceAgentResponse, SurfaceAgentResponseResult, SurfaceAgentMessage, SurfaceAgentStream, SurfaceAgentValidationResult, } from './agent.js';
|
|
7
10
|
export { SURFACE_AGENT_LIMITS, SURFACE_AGENT_RESPONSE_SCHEMA_VERSION, SURFACE_CATALOG_SCHEMA_VERSION, createSurfaceCatalogManifest, createSurfaceAgentResponseSchema, selectSurfaceCatalog, } from './agent-contract.js';
|
|
8
11
|
export type { SurfaceCatalogManifest } from './agent-contract.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { SURFACE_LIMITS, SURFACE_SCHEMA_VERSION } from './types.js';
|
|
2
2
|
export { validateSurfaceSpec } from './validation.js';
|
|
3
3
|
export { SURFACE_AGENT_SCHEMA_VERSION, buildSurfaceAgentPrompt, buildSurfaceAgentMessages, parseSurfaceAgentProposal, parseSurfaceAgentResponse, createSurfaceAgentStream, } from './agent.js';
|
|
4
|
+
export { SURFACE_AGENT_FENCE_TAG, splitSurfaceAgentText, } from './agent-text.js';
|
|
4
5
|
export { SURFACE_AGENT_LIMITS, SURFACE_AGENT_RESPONSE_SCHEMA_VERSION, SURFACE_CATALOG_SCHEMA_VERSION, createSurfaceCatalogManifest, createSurfaceAgentResponseSchema, selectSurfaceCatalog, } from './agent-contract.js';
|
|
5
6
|
export { SURFACE_EDIT_SCHEMA_VERSION, SURFACE_EDIT_LIMITS, createSurfaceRevision, applySurfaceEditProposal, createSurfaceEditSchema, buildSurfaceEditMessages, } from './edits.js';
|
|
6
7
|
// 只导出 JSON schema,不将可选 SVAR 渲染器加载到协议入口。
|
package/dist/localization.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface SurfaceMessages {
|
|
|
3
3
|
readonly renderErrorTitle: string;
|
|
4
4
|
readonly providerUnavailable: string;
|
|
5
5
|
readonly accessDenied?: string;
|
|
6
|
+
readonly invalidData?: string;
|
|
6
7
|
readonly metricNoData: string;
|
|
7
8
|
readonly metricInvalidData: string;
|
|
8
9
|
readonly chartLoading: string;
|
package/dist/localization.js
CHANGED
|
@@ -2,6 +2,7 @@ const englishMessages = {
|
|
|
2
2
|
renderErrorTitle: 'Surface could not be rendered',
|
|
3
3
|
providerUnavailable: 'Data provider is unavailable',
|
|
4
4
|
accessDenied: 'Access denied',
|
|
5
|
+
invalidData: 'Surface data is invalid',
|
|
5
6
|
metricNoData: 'No data',
|
|
6
7
|
metricInvalidData: 'Metric data is invalid',
|
|
7
8
|
chartLoading: 'Loading {title}',
|
|
@@ -30,6 +31,7 @@ const simplifiedChineseMessages = {
|
|
|
30
31
|
renderErrorTitle: '无法渲染 Surface',
|
|
31
32
|
providerUnavailable: '数据提供器不可用',
|
|
32
33
|
accessDenied: '无权访问',
|
|
34
|
+
invalidData: 'Surface 数据无效',
|
|
33
35
|
metricNoData: '暂无数据',
|
|
34
36
|
metricInvalidData: '指标数据无效',
|
|
35
37
|
chartLoading: '正在加载{title}',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/surface",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Validated declarative surfaces for svadmin dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@svadmin/core": ">=0.53.0 <0.
|
|
78
|
-
"@svadmin/ui": ">=0.73.0 <0.
|
|
77
|
+
"@svadmin/core": ">=0.53.0 <0.67.0",
|
|
78
|
+
"@svadmin/ui": ">=0.73.0 <0.93.0",
|
|
79
79
|
"svelte": "^5.56.10"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|