DenisFrezzato / hyper-ts

Type safe middleware architecture for HTTP servers
https://denisfrezzato.github.io/hyper-ts/
MIT License
392 stars 18 forks source link

Decoders to be able to be combined #77

Closed kalysr closed 2 years ago

kalysr commented 2 years ago

🚀 Feature request

I want all decoders to be able to be combined so that the typing is still preserved

Current Behavior

const _paramDecode = pipe(
  M.decodeParam('id', IntFromString.decode),
  M.mapLeft((e) => new Error(failure(e).join('\n'))),
);

const doAPIWork = (id: number) => M.fromTaskEither(TE.tryCatch(() => Promise.resolve([1, 2, 3]), E.toError));

const handler = pipe(
  _paramDecode,
  M.ichain((id) => doAPIWork(id)),
  M.ichain((numbers) =>
    pipe(
      M.status<Error>(H.Status.OK),
      M.ichain(() => M.json({ numbers }, E.toError)),
    ),
  ),
);

Desired Behavior

const handler = pipe(
  combine(
      _paramDecode,
      _paramDecode2,
      _queryDecode,
      _bodyDecode,
  ),
  M.ichain(([param1,param2,query,body]) => doAPIWork(param1,param2,query,body)),
  M.ichain((result) =>
    pipe(
      M.status<Error>(H.Status.OK),
      M.ichain(() => M.json( result, E.toError)),
    ),
  ),
);

My environment

Software Version(s)
fp-ts 2.11.8
hyper-ts 0.7.8
TypeScript 4.6.2
kylegoetz commented 2 years ago

I think

combine(
      _paramDecode,
      _paramDecode2,
      _queryDecode,
      _bodyDecode,
  ),

can be achieved currently with something like

pipe(
  H.bindTo('param', _paramDecode),
  H.bind('param2', () => _paramDecode),
  H.bind('query', () => _queryDecode),
  H.bind('body', () => _bodyDecode),
  H.ichain(({ param, param2, query, body }) => ...))

while preserving types of the params, query, and body you've decoded with.

kalysr commented 2 years ago

Thank you so much!