@seed-ship/mcp-ui-solid 5.5.1 → 5.6.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/CHANGELOG.md +47 -0
- package/dist/components/FormRenderer.cjs +13 -2
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormRenderer.js +13 -2
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +11 -0
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +11 -0
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/StreamingUIRenderer.cjs +49 -3
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +51 -5
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +62 -3
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +64 -5
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/context/MCPUITelemetryContext.cjs +25 -0
- package/dist/context/MCPUITelemetryContext.cjs.map +1 -0
- package/dist/context/MCPUITelemetryContext.d.ts +36 -0
- package/dist/context/MCPUITelemetryContext.d.ts.map +1 -0
- package/dist/context/MCPUITelemetryContext.js +25 -0
- package/dist/context/MCPUITelemetryContext.js.map +1 -0
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-ui-spec/dist/schemas.cjs +16 -5
- package/dist/mcp-ui-spec/dist/schemas.cjs.map +1 -1
- package/dist/mcp-ui-spec/dist/schemas.js +16 -5
- package/dist/mcp-ui-spec/dist/schemas.js.map +1 -1
- package/dist/services/telemetry.cjs +56 -0
- package/dist/services/telemetry.cjs.map +1 -0
- package/dist/services/telemetry.d.ts +87 -0
- package/dist/services/telemetry.d.ts.map +1 -0
- package/dist/services/telemetry.js +56 -0
- package/dist/services/telemetry.js.map +1 -0
- package/dist/services/validation.cjs +25 -24
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +26 -25
- package/dist/services/validation.js.map +1 -1
- package/package.json +2 -2
- package/src/components/FormRenderer.tsx +14 -0
- package/src/components/GenerativeUIErrorBoundary.tsx +17 -1
- package/src/components/StreamingUIRenderer.tsx +55 -3
- package/src/components/UIResourceRenderer.tsx +79 -3
- package/src/context/MCPUITelemetryContext.test.tsx +119 -0
- package/src/context/MCPUITelemetryContext.tsx +71 -0
- package/src/index.ts +15 -0
- package/src/services/telemetry.test.ts +134 -0
- package/src/services/telemetry.ts +149 -0
- package/src/services/validation.ts +43 -41
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -22,6 +22,9 @@ import {
|
|
|
22
22
|
ImageGalleryParamsSchema,
|
|
23
23
|
ActionGroupParamsSchema,
|
|
24
24
|
CodeComponentParamsSchema,
|
|
25
|
+
// v5.6.0 — added after spec@5.0.2 relaxations (deposium audit §M)
|
|
26
|
+
MapComponentParamsSchema,
|
|
27
|
+
FormComponentParamsSchema,
|
|
25
28
|
} from '@seed-ship/mcp-ui-spec'
|
|
26
29
|
import type {
|
|
27
30
|
UIComponent,
|
|
@@ -47,7 +50,7 @@ const KNOWN_COMPONENT_TYPES: Set<string> = new Set<ComponentType>([
|
|
|
47
50
|
])
|
|
48
51
|
|
|
49
52
|
/**
|
|
50
|
-
* Spec-driven validation dispatch table (B.1 — v5.5.0).
|
|
53
|
+
* Spec-driven validation dispatch table (B.1 — v5.5.0, expanded in v5.6.0).
|
|
51
54
|
*
|
|
52
55
|
* For each ComponentType where we delegate shape validation to a Zod schema
|
|
53
56
|
* from `@seed-ship/mcp-ui-spec`, this table maps:
|
|
@@ -56,13 +59,13 @@ const KNOWN_COMPONENT_TYPES: Set<string> = new Set<ComponentType>([
|
|
|
56
59
|
* pre-v5.5.0 `errors[].code` API contract — see MCP-UI-AUDIT-2026-04-26.md
|
|
57
60
|
* §I.3.a + §J.1)
|
|
58
61
|
*
|
|
62
|
+
* **v5.6.0** : `map` and `form` joined the dispatch after spec@5.0.2 relaxed
|
|
63
|
+
* their schemas (LatLngPoint union for map.center, regex relax for
|
|
64
|
+
* field.name) per deposium audit §L answers. Closed B.1 to **14/17 types**.
|
|
65
|
+
*
|
|
59
66
|
* Types deliberately omitted (kept on the imperative path):
|
|
60
67
|
* - `chart`, `table` — have rich imperative validators with their own
|
|
61
68
|
* codes (MISSING_DATA, DATA_LENGTH_MISMATCH, RESOURCE_LIMIT_EXCEEDED, …)
|
|
62
|
-
* - `form` — spec FormFieldSchema has strict regex on field
|
|
63
|
-
* names that could reject LLM-generated payloads. Conservative.
|
|
64
|
-
* - `map` — spec center is `tuple([number, number])`; production
|
|
65
|
-
* payloads use `{lat, lng}` objects. Avoid backward-compat regression.
|
|
66
69
|
* - `modal` — all params are optional; nothing to enforce.
|
|
67
70
|
* - `grid`, `footer`, `composite` — pass-through, validated elsewhere.
|
|
68
71
|
*/
|
|
@@ -79,6 +82,9 @@ const SPEC_VALIDATORS: Partial<Record<ComponentType, { schema: ZodSchema; legacy
|
|
|
79
82
|
'action-group': { schema: ActionGroupParamsSchema, legacyCode: 'EMPTY_ACTION_GROUP' },
|
|
80
83
|
code: { schema: CodeComponentParamsSchema, legacyCode: 'INVALID_CODE' },
|
|
81
84
|
artifact: { schema: ArtifactComponentParamsSchema, legacyCode: 'INVALID_ARTIFACT' },
|
|
85
|
+
// v5.6.0 additions
|
|
86
|
+
form: { schema: FormComponentParamsSchema, legacyCode: 'EMPTY_FORM' },
|
|
87
|
+
map: { schema: MapComponentParamsSchema, legacyCode: 'INVALID_MAP' },
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
/**
|
|
@@ -677,35 +683,49 @@ export function validateComponent(
|
|
|
677
683
|
errors.push(...(sizeResult.errors || []))
|
|
678
684
|
}
|
|
679
685
|
|
|
680
|
-
// Type-specific validation (B.1 — v5.5.0).
|
|
686
|
+
// Type-specific validation (B.1 — v5.5.0, expanded v5.6.0).
|
|
681
687
|
//
|
|
682
|
-
//
|
|
683
|
-
// SPEC_VALIDATORS. The
|
|
684
|
-
// need cross-field consistency, resource limits, or
|
|
685
|
-
//
|
|
688
|
+
// 14 types delegate shape validation to Zod schemas in `mcp-ui-spec` via
|
|
689
|
+
// SPEC_VALIDATORS. The 3 remaining types stay imperative because they
|
|
690
|
+
// need cross-field consistency, resource limits, or have nothing to validate
|
|
691
|
+
// (see SPEC_VALIDATORS docstring).
|
|
686
692
|
const specValidator = SPEC_VALIDATORS[component.type]
|
|
687
693
|
if (specValidator) {
|
|
688
694
|
const result = specValidator.schema.safeParse(component.params)
|
|
689
695
|
if (!result.success) {
|
|
690
696
|
errors.push(...mapZodIssuesToErrors(result.error.issues, specValidator.legacyCode))
|
|
691
697
|
}
|
|
692
|
-
//
|
|
693
|
-
//
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
698
|
+
// Post-spec chained checks. Skipped when the shape parse failed to avoid
|
|
699
|
+
// cascading errors on already-broken payloads.
|
|
700
|
+
if (result.success) {
|
|
701
|
+
// Iframe + video: domain whitelist
|
|
702
|
+
if (component.type === 'iframe' || component.type === 'video') {
|
|
703
|
+
const url = (component.params as { url?: string })?.url
|
|
704
|
+
if (typeof url === 'string') {
|
|
705
|
+
const domainResult = validateIframeDomain(url, {
|
|
706
|
+
policy: options?.iframePolicy,
|
|
707
|
+
customDomains: options?.customIframeDomains,
|
|
708
|
+
})
|
|
709
|
+
if (!domainResult.valid) {
|
|
710
|
+
errors.push(...(domainResult.errors || []))
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
// Map (v5.6.0): center OR markers required. Spec has both .optional()
|
|
715
|
+
// since auto-center from markers is supported, but we need ONE of them.
|
|
716
|
+
if (component.type === 'map') {
|
|
717
|
+
const mapParams = component.params as { center?: unknown; markers?: unknown[] }
|
|
718
|
+
if (!mapParams.center && (!Array.isArray(mapParams.markers) || mapParams.markers.length === 0)) {
|
|
719
|
+
errors.push({
|
|
720
|
+
path: 'params',
|
|
721
|
+
message: 'Map must have center or markers',
|
|
722
|
+
code: 'INVALID_MAP',
|
|
723
|
+
})
|
|
704
724
|
}
|
|
705
725
|
}
|
|
706
726
|
}
|
|
707
727
|
} else {
|
|
708
|
-
// Imperative path for chart/table/
|
|
728
|
+
// Imperative path for chart/table/modal/grid/footer/composite.
|
|
709
729
|
switch (component.type) {
|
|
710
730
|
case 'chart': {
|
|
711
731
|
const chartResult = validateChartComponent(component.params as ChartComponentParams, limits)
|
|
@@ -723,24 +743,6 @@ export function validateComponent(
|
|
|
723
743
|
break
|
|
724
744
|
}
|
|
725
745
|
|
|
726
|
-
case 'form': {
|
|
727
|
-
const formParams = component.params as { fields?: unknown[] }
|
|
728
|
-
if (!Array.isArray(formParams.fields) || formParams.fields.length === 0) {
|
|
729
|
-
errors.push({ path: 'params.fields', message: 'Form must have non-empty fields array', code: 'EMPTY_FORM' })
|
|
730
|
-
}
|
|
731
|
-
break
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
case 'map': {
|
|
735
|
-
// Map can auto-detect center from markers, so center is not strictly required.
|
|
736
|
-
// Spec MapComponentParamsSchema would be too strict (tuple-only center) — kept imperative.
|
|
737
|
-
const mapParams = component.params as { center?: unknown; markers?: unknown[] }
|
|
738
|
-
if (!mapParams.center && (!Array.isArray(mapParams.markers) || mapParams.markers.length === 0)) {
|
|
739
|
-
errors.push({ path: 'params', message: 'Map must have center or markers', code: 'INVALID_MAP' })
|
|
740
|
-
}
|
|
741
|
-
break
|
|
742
|
-
}
|
|
743
|
-
|
|
744
746
|
case 'modal':
|
|
745
747
|
// Modal is valid with minimal params (title optional, content can be children).
|
|
746
748
|
break
|