Effect CommunityEC
Effect Community2y ago
3 replies
Freeman

Using transform without duplicating schemas?

Hey! I have a schema like this:
const RawDrawingSchema = Schema.Struct({
  id: Schema.Int.pipe(Schema.fromBrand(DrawingIdBrand)),
  discipline: Schema.String,
  number: Schema.String,
  title: Schema.String,
  obsolete: Schema.Boolean,
  current_revision: Schema.NullOr(
    Schema.Struct({
      ...
    })
  ),
});

I'd like to add an external_ prefix to all properties (excluding nested properties).

The most straightforward solution I could find is doing:
const R = Schema.transform(
  Schema.Array(RawDrawingSchema),
  Schema.Array(
    Schema.Struct({
      external_id: RawDrawingSchema.fields.id,
      external_number: RawDrawingSchema.fields.number,
      external_title: RawDrawingSchema.fields.title,
      external_discipline: RawDrawingSchema.fields.discipline,
      external_obsolete: RawDrawingSchema.fields.obsolete,
      external_current_revision: RawDrawingSchema.fields.current_revision,
    } satisfies Record<`external_${keyof typeof RawDrawingSchema.Type}`, Schema.Any>)
  ),
  {
    decode: (data) =>
      data.map((item) => {
        return {
          external_current_revision: item.current_revision,
          external_discipline: item.discipline,
          // ...
        };
      }),
    encode: (data) =>
      data.map((item) => {
        return {
          current_revision: item.external_current_revision,
          id: DrawingIdBrand(item.external_id),
          // ...
        };
      }),
    strict: true,
  }
);


pipe(
  // ...
  Effect.flatMap((response) => Schema.decodeUnknown(Schema.Array(RawDrawingSchema), { onExcessProperty: "preserve" })(response)),
  Effect.andThen((encoded) => Schema.decode(R)(encoded)),
)


However, I feel like this could just be done at the type-level with a type that recursively adds external_ to every property, rather than manually re-writing the Schema.

Is there a more elegant way to do this/am I doing it right in the first place? Haha. Thanks in advance!
Was this page helpful?