diff --git a/packages/examples/packages/browserify-plugin/snap.manifest.json b/packages/examples/packages/browserify-plugin/snap.manifest.json index b009194e29..f1e34c3f64 100644 --- a/packages/examples/packages/browserify-plugin/snap.manifest.json +++ b/packages/examples/packages/browserify-plugin/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "zIDqJzXMi7kdr4+TOIKO1lOK4o3r60fEDRMO4Q6lXzk=", + "shasum": "2WLcpc3RXg2Up0zeSMxWS/2rsVI1bC1iHCHAhzc3DOA=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/browserify/snap.manifest.json b/packages/examples/packages/browserify/snap.manifest.json index 6dc26feea6..14eb4eb126 100644 --- a/packages/examples/packages/browserify/snap.manifest.json +++ b/packages/examples/packages/browserify/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "coTp9c/ZNMaIGqnTbDMfSpt867Gyq6kQCbmgsZzTARg=", + "shasum": "LQYiFCEu2fQXCuzfYHVpFfqffCbzzUjaqH7kPwgBfNc=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/cronjobs/snap.manifest.json b/packages/examples/packages/cronjobs/snap.manifest.json index 0352aa6844..c490ca4458 100644 --- a/packages/examples/packages/cronjobs/snap.manifest.json +++ b/packages/examples/packages/cronjobs/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "9/KE/yjYAfOTNAgd0D0SYVY8JBFf+NQuiEAQFw0NOC8=", + "shasum": "cvn98L15eJyKHx8ILZMXdWnldchVezqFyEEBPbzPphA=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/dialogs/snap.manifest.json b/packages/examples/packages/dialogs/snap.manifest.json index f8fe7debe8..1cf65f3d49 100644 --- a/packages/examples/packages/dialogs/snap.manifest.json +++ b/packages/examples/packages/dialogs/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "fCeqfbW1isFwXBPuM3RaAEtcR3J0Lv31fQ57rFNRwfs=", + "shasum": "3EvoIyaDBktcyCt1ctHZuF8NyLWcvwudTHutInzJLh8=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/ethers-js/snap.manifest.json b/packages/examples/packages/ethers-js/snap.manifest.json index f49cd27d1e..51d5dd732f 100644 --- a/packages/examples/packages/ethers-js/snap.manifest.json +++ b/packages/examples/packages/ethers-js/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "V+BzJMukP8qstaXg0Wad4UP9+TEASCC3BI1aWh1x88I=", + "shasum": "tiSVGL8yltFcza2kKeinRFy78EpJjAOmNq7VdjUuZCA=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/images/snap.manifest.json b/packages/examples/packages/images/snap.manifest.json index 1649ad313b..7e1c5eadae 100644 --- a/packages/examples/packages/images/snap.manifest.json +++ b/packages/examples/packages/images/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "lkNwxRYoirSS7KXzcQq+yRWJuQybHll6JMFFwCiNzJM=", + "shasum": "3BZDz8Bb5rS3LZtzyJzWf256FQyPUpau6fSJrdnb6z4=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/invoke-snap/packages/core-signer/snap.manifest.json b/packages/examples/packages/invoke-snap/packages/core-signer/snap.manifest.json index b7a47cf40a..986a33977b 100644 --- a/packages/examples/packages/invoke-snap/packages/core-signer/snap.manifest.json +++ b/packages/examples/packages/invoke-snap/packages/core-signer/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "Of48MD2Ff6x699xG59ZcPr/sUJ3Eh2/L5jGI5m/oG0I=", + "shasum": "z7oshK7wm/kA4Oqm4je3l4jzoceecqc6YKLvzKqhD/g=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/signature-insights/snap.manifest.json b/packages/examples/packages/signature-insights/snap.manifest.json index 3ffd8cd012..0df0ec107e 100644 --- a/packages/examples/packages/signature-insights/snap.manifest.json +++ b/packages/examples/packages/signature-insights/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "JtC90PiqLl5E6zsaCbNijJztIbFuRTrAb/iFZqVWn58=", + "shasum": "ksDM4Au4/toUxZEMdG1827cC9nJo/ZOHUGOA/kmQF/Q=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/transaction-insights/snap.manifest.json b/packages/examples/packages/transaction-insights/snap.manifest.json index 98c4c8f96e..0f09955981 100644 --- a/packages/examples/packages/transaction-insights/snap.manifest.json +++ b/packages/examples/packages/transaction-insights/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "yPO8YJN8Obq9TqQ3yZaPjurJPu+f2Ohlwmup0Rrwn9o=", + "shasum": "7bsB6l4qPdrB12apSpFqD0i4DNZ65OOrgvyqu0dj0Mc=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/snaps-sdk/src/internals/structs.ts b/packages/snaps-sdk/src/internals/structs.ts index 8d559b5baf..f635a8422f 100644 --- a/packages/snaps-sdk/src/internals/structs.ts +++ b/packages/snaps-sdk/src/internals/structs.ts @@ -2,12 +2,11 @@ import type { AnyStruct, Infer, InferStructTuple } from '@metamask/superstruct'; import { Struct, define, - is, literal as superstructLiteral, union as superstructUnion, } from '@metamask/superstruct'; import type { PlainObject } from '@metamask/utils'; -import { hasProperty, isPlainObject } from '@metamask/utils'; +import { hasProperty, isObject } from '@metamask/utils'; import type { EnumToUnion } from './helpers'; @@ -99,16 +98,27 @@ export function typedUnion( ) .flat(Infinity); const types = flatStructs.map(({ schema }) => schema.type.type); + const structMap = flatStructs.reduce>( + (accumulator, struct) => { + accumulator[JSON.parse(struct.schema.type.type)] = struct; + return accumulator; + }, + {}, + ); return new Struct({ type: 'union', schema: flatStructs, *entries(value, context) { - if (!isPlainObject(value) || !hasProperty(value, 'type')) { + if ( + !isObject(value) || + !hasProperty(value, 'type') || + typeof value.type !== 'string' + ) { return; } const { type } = value; - const struct = flatStructs.find(({ schema }) => is(type, schema.type)); + const struct = structMap[type]; if (!struct) { return; @@ -119,12 +129,16 @@ export function typedUnion( } }, coercer(value, context) { - if (!isPlainObject(value) || !hasProperty(value, 'type')) { + if ( + !isObject(value) || + !hasProperty(value, 'type') || + typeof value.type !== 'string' + ) { return value; } const { type } = value; - const struct = flatStructs.find(({ schema }) => is(type, schema.type)); + const struct = structMap[type]; if (struct) { return struct.coercer(value, context); } @@ -132,16 +146,14 @@ export function typedUnion( return value; }, // At this point we know the value to be an object. - *refiner(value: PlainObject, context) { - const struct = flatStructs.find(({ schema }) => - is(value.type, schema.type), - ); + *refiner(value: PlainObject & { type: string }, context) { + const struct = structMap[value.type]; yield* struct.refiner(value, context); }, validator(value, context) { if ( - !isPlainObject(value) || + !isObject(value) || !hasProperty(value, 'type') || typeof value.type !== 'string' ) { @@ -152,7 +164,7 @@ export function typedUnion( const { type } = value; - const struct = flatStructs.find(({ schema }) => is(type, schema.type)); + const struct = structMap[type]; if (struct) { // This only validates the root of the struct, entries does the rest of the work. diff --git a/packages/snaps-sdk/src/jsx/validation.ts b/packages/snaps-sdk/src/jsx/validation.ts index b056df937d..bfe72209fa 100644 --- a/packages/snaps-sdk/src/jsx/validation.ts +++ b/packages/snaps-sdk/src/jsx/validation.ts @@ -149,16 +149,14 @@ function children( Nestable | InferStructTuple[number] | boolean | null>, null > { + const potentialUnion = structs.length === 1 ? structs[0] : nullUnion(structs); return nestable( nullable( selectiveUnion((value) => { if (typeof value === 'boolean') { return boolean(); } - if (structs.length === 1) { - return structs[0]; - } - return nullUnion(structs); + return potentialUnion; }), ), ) as unknown as Struct< diff --git a/packages/snaps-sdk/src/ui/components/address.ts b/packages/snaps-sdk/src/ui/components/address.ts index b90871e54a..e59810bb38 100644 --- a/packages/snaps-sdk/src/ui/components/address.ts +++ b/packages/snaps-sdk/src/ui/components/address.ts @@ -1,7 +1,8 @@ import type { Infer } from '@metamask/superstruct'; -import { assign, literal, object } from '@metamask/superstruct'; +import { assign, object } from '@metamask/superstruct'; import { HexChecksumAddressStruct } from '@metamask/utils'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/button.ts b/packages/snaps-sdk/src/ui/components/button.ts index 6103999e19..7daff7e538 100644 --- a/packages/snaps-sdk/src/ui/components/button.ts +++ b/packages/snaps-sdk/src/ui/components/button.ts @@ -1,14 +1,7 @@ import type { Infer } from '@metamask/superstruct'; -import { - assign, - literal, - object, - optional, - string, - union, -} from '@metamask/superstruct'; +import { assign, object, optional, string, union } from '@metamask/superstruct'; -import { enumValue } from '../../internals'; +import { enumValue, literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/copyable.ts b/packages/snaps-sdk/src/ui/components/copyable.ts index 1825dc127f..81478f922f 100644 --- a/packages/snaps-sdk/src/ui/components/copyable.ts +++ b/packages/snaps-sdk/src/ui/components/copyable.ts @@ -2,12 +2,12 @@ import type { Infer } from '@metamask/superstruct'; import { assign, boolean, - literal, object, optional, string, } from '@metamask/superstruct'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/divider.ts b/packages/snaps-sdk/src/ui/components/divider.ts index 31e2896f6f..f3d5894bfb 100644 --- a/packages/snaps-sdk/src/ui/components/divider.ts +++ b/packages/snaps-sdk/src/ui/components/divider.ts @@ -1,6 +1,7 @@ import type { Infer } from '@metamask/superstruct'; -import { assign, literal, object } from '@metamask/superstruct'; +import { assign, object } from '@metamask/superstruct'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { NodeStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/form.ts b/packages/snaps-sdk/src/ui/components/form.ts index 6aaed3c0ab..d3a7475e8d 100644 --- a/packages/snaps-sdk/src/ui/components/form.ts +++ b/packages/snaps-sdk/src/ui/components/form.ts @@ -1,15 +1,9 @@ import type { Infer } from '@metamask/superstruct'; -import { - array, - assign, - literal, - object, - string, - union, -} from '@metamask/superstruct'; +import { array, assign, object, string, union } from '@metamask/superstruct'; import { ButtonStruct } from './button'; import { InputStruct } from './input'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { NodeStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/heading.ts b/packages/snaps-sdk/src/ui/components/heading.ts index 2c8384b69d..4a4e3a5dfd 100644 --- a/packages/snaps-sdk/src/ui/components/heading.ts +++ b/packages/snaps-sdk/src/ui/components/heading.ts @@ -1,6 +1,7 @@ import type { Infer } from '@metamask/superstruct'; -import { assign, literal, object, string } from '@metamask/superstruct'; +import { assign, object, string } from '@metamask/superstruct'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/image.ts b/packages/snaps-sdk/src/ui/components/image.ts index a3639b8fb5..a5a4545ca7 100644 --- a/packages/snaps-sdk/src/ui/components/image.ts +++ b/packages/snaps-sdk/src/ui/components/image.ts @@ -1,7 +1,7 @@ import type { Infer } from '@metamask/superstruct'; -import { assign, literal, object } from '@metamask/superstruct'; +import { assign, object } from '@metamask/superstruct'; -import { svg } from '../../internals'; +import { svg, literal } from '../../internals'; import { createBuilder } from '../builder'; import { NodeStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/input.ts b/packages/snaps-sdk/src/ui/components/input.ts index d58c98cd14..4bccd62a0c 100644 --- a/packages/snaps-sdk/src/ui/components/input.ts +++ b/packages/snaps-sdk/src/ui/components/input.ts @@ -1,14 +1,7 @@ import type { Infer } from '@metamask/superstruct'; -import { - assign, - literal, - object, - optional, - string, - union, -} from '@metamask/superstruct'; +import { assign, object, optional, string, union } from '@metamask/superstruct'; -import { enumValue } from '../../internals'; +import { enumValue, literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/panel.ts b/packages/snaps-sdk/src/ui/components/panel.ts index 7832039d78..601dbe8128 100644 --- a/packages/snaps-sdk/src/ui/components/panel.ts +++ b/packages/snaps-sdk/src/ui/components/panel.ts @@ -1,5 +1,5 @@ import type { Infer, Struct } from '@metamask/superstruct'; -import { array, assign, lazy, literal, object } from '@metamask/superstruct'; +import { array, assign, lazy, object } from '@metamask/superstruct'; import { AddressStruct } from './address'; import { ButtonStruct } from './button'; @@ -12,7 +12,7 @@ import { InputStruct } from './input'; import { RowStruct } from './row'; import { SpinnerStruct } from './spinner'; import { TextStruct } from './text'; -import { typedUnion } from '../../internals'; +import { typedUnion, literal } from '../../internals'; import { createBuilder } from '../builder'; import { NodeStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/row.ts b/packages/snaps-sdk/src/ui/components/row.ts index 4d2c665edd..3464d91a99 100644 --- a/packages/snaps-sdk/src/ui/components/row.ts +++ b/packages/snaps-sdk/src/ui/components/row.ts @@ -1,17 +1,10 @@ import type { Infer } from '@metamask/superstruct'; -import { - assign, - literal, - object, - string, - optional, - union, -} from '@metamask/superstruct'; +import { assign, object, string, optional, union } from '@metamask/superstruct'; import { AddressStruct } from './address'; import { ImageStruct } from './image'; import { TextStruct } from './text'; -import { enumValue } from '../../internals'; +import { enumValue, literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/spinner.ts b/packages/snaps-sdk/src/ui/components/spinner.ts index 8494e48484..cbe530ed23 100644 --- a/packages/snaps-sdk/src/ui/components/spinner.ts +++ b/packages/snaps-sdk/src/ui/components/spinner.ts @@ -1,6 +1,7 @@ import type { Infer } from '@metamask/superstruct'; -import { assign, literal, object } from '@metamask/superstruct'; +import { assign, object } from '@metamask/superstruct'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { NodeStruct, NodeType } from '../nodes'; diff --git a/packages/snaps-sdk/src/ui/components/text.ts b/packages/snaps-sdk/src/ui/components/text.ts index c6dc6522ca..f993f3fb0f 100644 --- a/packages/snaps-sdk/src/ui/components/text.ts +++ b/packages/snaps-sdk/src/ui/components/text.ts @@ -2,12 +2,12 @@ import type { Infer } from '@metamask/superstruct'; import { assign, boolean, - literal, object, optional, string, } from '@metamask/superstruct'; +import { literal } from '../../internals'; import { createBuilder } from '../builder'; import { LiteralStruct, NodeType } from '../nodes';