Skip to content

Commit 2c8d5bb

Browse files
fix: Improve a couple of error messages for UI components (#3625)
Improve a couple of error messages when validating UI components that use the `children` utility method.
1 parent a8e0d22 commit 2c8d5bb

File tree

2 files changed

+66
-21
lines changed

2 files changed

+66
-21
lines changed

packages/snaps-sdk/src/internals/structs.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
any,
99
} from '@metamask/superstruct';
1010

11+
import { nullUnion } from './jsx';
1112
import {
1213
enumValue,
1314
literal,
@@ -18,6 +19,7 @@ import {
1819
import type { BoxElement } from '../jsx';
1920
import { Footer, Icon, Text, Button, Box } from '../jsx';
2021
import {
22+
BoldStruct,
2123
BoxStruct,
2224
FieldStruct,
2325
FooterStruct,
@@ -86,6 +88,33 @@ describe('typedUnion', () => {
8688
);
8789
});
8890

91+
it('validates when nested in a union including primitives', () => {
92+
const stringUnion = nullUnion([
93+
string(),
94+
typedUnion([TextStruct, BoldStruct]),
95+
]);
96+
97+
// @ts-expect-error Invalid props.
98+
const result = validate(Text({}), stringUnion);
99+
100+
expect(result[0]?.message).toBe(
101+
'Expected the value to satisfy a union of `string | union`, but received: [object Object]',
102+
);
103+
});
104+
105+
it('validates when nested in a union including non-typed objects', () => {
106+
const nonTypedObjectUnion = nullUnion([
107+
typedUnion([TextStruct, BoldStruct]),
108+
object({ type: literal('bar') }),
109+
]);
110+
111+
const result = validate({ type: 'abc' }, nonTypedObjectUnion);
112+
113+
expect(result[0]?.message).toBe(
114+
'Expected the value to satisfy a union of `union | object`, but received: [object Object]',
115+
);
116+
});
117+
89118
it('validates refined elements', () => {
90119
const refinedUnionStruct = typedUnion([BoxStruct, FooterStruct]);
91120
const result = validate(

packages/snaps-sdk/src/jsx/validation.ts

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -615,11 +615,15 @@ export const FieldStruct: Describe<FieldElement> = element('Field', {
615615
*/
616616
export const BoldStruct: Describe<BoldElement> = element('Bold', {
617617
children: children([
618-
string(),
619-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
620-
lazy(() => ItalicStruct) as unknown as Struct<
621-
SnapElement<JsonObject, 'Italic'>
622-
>,
618+
selectiveUnion((value) => {
619+
if (typeof value === 'string') {
620+
return string();
621+
}
622+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
623+
return ItalicStruct as unknown as Struct<
624+
SnapElement<JsonObject, 'Italic'>
625+
>;
626+
}),
623627
]),
624628
});
625629

@@ -628,10 +632,13 @@ export const BoldStruct: Describe<BoldElement> = element('Bold', {
628632
*/
629633
export const ItalicStruct: Describe<ItalicElement> = element('Italic', {
630634
children: children([
631-
string(),
632-
lazy(() => BoldStruct) as unknown as Struct<
633-
SnapElement<JsonObject, 'Bold'>
634-
>,
635+
selectiveUnion((value) => {
636+
if (typeof value === 'string') {
637+
return string();
638+
}
639+
640+
return BoldStruct as unknown as Struct<SnapElement<JsonObject, 'Bold'>>;
641+
}),
635642
]),
636643
});
637644

@@ -774,11 +781,18 @@ export const HeadingStruct: Describe<HeadingElement> = element('Heading', {
774781
export const LinkStruct: Describe<LinkElement> = element('Link', {
775782
href: string(),
776783
children: children([
777-
FormattingStruct,
778-
string(),
779-
IconStruct,
780-
ImageStruct,
781-
AddressStruct,
784+
selectiveUnion((value) => {
785+
if (typeof value === 'string') {
786+
return string();
787+
}
788+
789+
return typedUnion([
790+
FormattingStruct,
791+
IconStruct,
792+
ImageStruct,
793+
AddressStruct,
794+
]);
795+
}),
782796
]),
783797
});
784798

@@ -896,13 +910,15 @@ export const TooltipStruct: Describe<TooltipElement> = element('Tooltip', {
896910
*/
897911
export const BannerStruct: Describe<BannerElement> = element('Banner', {
898912
children: children([
899-
TextStruct,
900-
LinkStruct,
901-
IconStruct,
902-
ButtonStruct,
903-
BoldStruct,
904-
ItalicStruct,
905-
SkeletonStruct,
913+
typedUnion([
914+
TextStruct,
915+
LinkStruct,
916+
IconStruct,
917+
ButtonStruct,
918+
BoldStruct,
919+
ItalicStruct,
920+
SkeletonStruct,
921+
]),
906922
]),
907923
title: string(),
908924
severity: union([

0 commit comments

Comments
 (0)