Effect CommunityEC
Effect Community8mo ago
1 reply
Yatogami

Bidirectional schema encoding/decoding with BrandedType

Hi ! I was playing around with Schema using transform especially to transform a plain JWT token into a encoded token. But for some reason encoding the value using Schema.encode return string instead of the BrandedType. Am I missing something ?

Code example
export class PlainToken extends Schema.Class<PlainToken>("PlainToken")({
  id: Schema.UUID,
  name: Schema.NonEmptyTrimmedString,
}) {}

export const EncodedToken = Schema.NonEmptyTrimmedString.pipe(
  Schema.brand("EncodedToken")
);

export type EncodedToken = typeof EncodedToken.Type;

export const Token = Schema.transformOrFail(EncodedToken, PlainToken, {
  strict: true,
  decode: (fromA, _, ast) =>
    Effect.gen(function* () {
      const jwtService = yield* JwtService;

      return yield* jwtService
        .decode(fromA)
        .pipe(
          Effect.mapError((e) => new ParseResult.Type(ast, fromA, e.message))
        );
    }),
  encode: (toI, _, ast) =>
    Effect.gen(function* () {
      const jwtService = yield* JwtService;

      return yield* jwtService
        .encode(toI)
        .pipe(
          Effect.mapError((e) => new ParseResult.Type(ast, toI, e.message))
        );
    }),
});

// Effect.Effect<string, ParseResult.ParseError, JwtService> -- Expecting <EncodedToken> as value of the effect
const x = Schema.encode(Token)(PlainToken.make({ id: "123", name: "jane" }));

// Effect.Effect<PlainToken, ParseResult.ParseError, JwtService>
const y = Schema.decode(Token)(EncodedToken.make("123"));
Was this page helpful?