Git Product home page Git Product logo

Comments (8)

anymaniax avatar anymaniax commented on May 27, 2024 1

Both will be in the next release

from orval.

melloware avatar melloware commented on May 27, 2024 1

Sure use Discord?

from orval.

marceloverdijk avatar marceloverdijk commented on May 27, 2024

On a related note, is there a way to type-safe the response as well?

from orval.

anymaniax avatar anymaniax commented on May 27, 2024

I am on it and for the response. A zod schema is already generated but not automatically checked. I am not sure how to do it properly if you have an idea or example I am open to add it

from orval.

anymaniax avatar anymaniax commented on May 27, 2024

something like this would do the job I will add it as an option and we can iterate on it

const responseValidator = factory.createMiddleware(async (c, next) => {
  await next();

  const data = c.res.json();

  const result = await createPetsResponse.safeParseAsync(data);

  if (!result.success) {
    c.res = new Response(JSON.stringify(result), {
      status: 400,
      headers: {
        'Content-Type': 'application/json',
      },
    });
  }

  c.res = new Response(c.res.body, c.res);
});

from orval.

anymaniax avatar anymaniax commented on May 27, 2024

I ended with something like this

// based on https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts
import type { z, ZodSchema, ZodError } from 'zod';
import {
  Context,
  Env,
  Input,
  MiddlewareHandler,
  TypedResponse,
  ValidationTargets,
} from 'hono';
type HasUndefined<T> = undefined extends T ? true : false;

type Hook<T, E extends Env, P extends string, O = {}> = (
  result:
    | { success: true; data: T }
    | { success: false; error: ZodError; data: T },
  c: Context<E, P>,
) =>
  | Response
  | Promise<Response>
  | void
  | Promise<Response | void>
  | TypedResponse<O>;

export const zResponseValidtor =
  <
    T extends ZodSchema,
    Target extends keyof ValidationTargets,
    E extends Env,
    P extends string,
    In = z.input<T>,
    Out = z.output<T>,
    I extends Input = {
      in: HasUndefined<In> extends true
        ? {
            [K in Target]?: K extends 'json'
              ? In
              : HasUndefined<keyof ValidationTargets[K]> extends true
              ? { [K2 in keyof In]?: ValidationTargets[K][K2] }
              : { [K2 in keyof In]: ValidationTargets[K][K2] };
          }
        : {
            [K in Target]: K extends 'json'
              ? In
              : HasUndefined<keyof ValidationTargets[K]> extends true
              ? { [K2 in keyof In]?: ValidationTargets[K][K2] }
              : { [K2 in keyof In]: ValidationTargets[K][K2] };
          };
      out: { [K in Target]: Out };
    },
    V extends I = I,
  >(
    schema: T,
    hook?: Hook<z.infer<T>, E, P>,
  ): MiddlewareHandler<E, P, V> =>
  async (c, next) => {
    await next();

    const clonedResponse = c.res.clone();

    let value: unknown;
    try {
      value = await clonedResponse.json();
    } catch {
      const message = 'Malformed JSON in response';
      c.res = new Response(message, { status: 400 });
    }

    const result = await schema.safeParseAsync(value);

    if (hook) {
      const hookResult = hook({ data: value, ...result }, c);
      if (hookResult) {
        if (hookResult instanceof Response || hookResult instanceof Promise) {
          const hookResponse = await hookResult;

          if (hookResponse instanceof Response) {
            c.res = new Response(hookResponse.body, hookResponse);
          }
        }
        if (
          'response' in hookResult &&
          hookResult.response instanceof Response
        ) {
          c.res = new Response(hookResult.response.body, hookResult.response);
        }
      }
    }

    if (!result.success) {
      c.res = new Response(JSON.stringify(result), {
        status: 400,
        headers: {
          'Content-Type': 'application/json',
        },
      });
    }
  };

from orval.

marceloverdijk avatar marceloverdijk commented on May 27, 2024

Thx @anymaniax , looking forward to it.
For the response typing, to be honest, I had no idea how to do it; so anything would be good ;-)

My main problem with responses in general is that to much is send to the client; e.g. fields with data that is not meant to be exposed.

from orval.

marceloverdijk avatar marceloverdijk commented on May 27, 2024

Thx @anymaniax I can confirm the issue Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345) is solved with latest release 💪

For response validation I have some questions, but I think the best place would be Discord?

from orval.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.