Transforming Nested Object Fields in Schema Without 'Unsupported schema' Error

I have a field called rarity defined as an object { name: string; color: string }. I want to parse this field and transform it into { rarity: rarity.name, color: rarity.color }, effectively moving name and color to the top level with rarity being the name value.

The challenge is to achieve this transformation without duplicating code everywhere, and I couldn't find a proper way to do this in the documentation.

Here's the code I've tried so far, broken down into parts:

1. Adding a Default Value Transformation:

const addDefault = S.transform(S.String, {
  strict: true,
  decode: (val) => val || "",
  encode: (val) => val,
})
const StringWithDefault = S.NullOr(S.String).pipe(addDefault);


2. Defining the _Rarity Structure:

const Rarity = S.Struct({
  name: S.String,
  color: S.String.pipe(
    S.transform(S.String, {
      strict: true,
      decode: (s) => s.substring(1),//remove #
      encode: (s) => s,
    }),
  ),
})


3. Defining the Sticker Structure:

export const Sticker = S.Struct({
  id: S.String,
  name: S.String,
  description: StringWithDefault,
  rarity: Rarity,
  type: S.String,
  crates: S.Array(S.partialWith(Crate, { exact: true })),
  market_hash_name: StringWithDefault,
})


4. Attempting to Transform the Sticker :

Sticker.pipe((struct) =>
  struct.pipe(S.transform(
    S.Struct({
      ...struct.fields,
      color: S.String,
      rarity: S.String,
    }),
    {
      strict: true,
      encode: (_struct) => ({
        ..._struct,
        rarity: { color: _struct.color, name: _struct.rarity },
      }),
      decode: (_struct) => ({
        ..._struct,
        rarity: _struct.rarity.name,
        color: _struct.rarity.color,
      }),
    },
  )), S.omit("type"))

However, this code doesn't work and gives the error: error: Uncaught (in promise) Error: Unsupported schema

Additionally, is there a way to add a default decode value if the parsed value is
null
?
Was this page helpful?