ecyrbe / zodios

typescript http client and server with zod validation
https://www.zodios.org/
MIT License
1.71k stars 46 forks source link

Transforming parameters causes incorrect type to be inferred #91

Closed alex-way closed 2 years ago

alex-way commented 2 years ago

It's me again!

I've got a small issue which I'm hoping isn't a pain to resolve.

Essentially when performing a transform on a schema for a parameter, it seemingly infers the incorrect type. I've added an example below:

const refreshClient = new Zodios(url, [
  {
    method: "post",
    path: "/oauth_token.do",
    alias: "getRefreshTokenWithCode",
    parameters: [
      {
        name: "body",
        type: "Body",
        schema: z
          .object({
            code: z.string(),
            client_id: z.string(),
            client_secret: z.string(),
            redirect_uri: z.string().url(),
          })
          .transform(
            (value) =>
          ),
      },
    ],
    response: z.object({
      access_token: z.string(),
      refresh_token: z.string(),
    }),
  },
] as const);

const refreshResponse = await refreshClient.getRefreshTokenWithCode(
      {
      code,
      client_id: process.env.SERVICENOW__CLIENT_ID,
      client_secret: process.env.SERVICENOW__CLIENT_SECRET,
      redirect_uri: process.env.SERVICENOW__REDIRECT_URI,
    }
  );

image

What I'd like to be able to do is to effectively simplify the inputs via a transform?

ecyrbe commented 2 years ago

Hello alex,

I recognize oauth with application/x-www-form-urlencoded data. Take a look at the docs, zodios since the plugin rework now supports application/x-www-form-urlencoded natively, you don't need to use zod transform.

So you can just write it like that :

const refreshClient = new Zodios(url, [
  {
    method: "post",
    path: "/oauth_token.do",
    alias: "getRefreshTokenWithCode",
   requestFormat: 'form-url',
    parameters: [
      {
        name: "body",
        type: "Body",
        schema: z
          .object({
            code: z.string(),
            client_id: z.string(),
            client_secret: z.string(),
            redirect_uri: z.string().url(),
          }),
      },
    ],
    response: z.object({
      access_token: z.string(),
      refresh_token: z.string(),
    }),
  },
] as const);

you can take a look at the docs here

Tell me if this handles your use case.

alex-way commented 2 years ago

Ah I did see that option but wasn't 100% certain that it did what I expected it to (I probably should've tested it). This fits my use case here perfectly but I do have another use case where I'd like to do a somewhat similar transformation. For example I want to have two inputs which I'll transform into one via a template literal. Happy to raise a separate request however 😊

ecyrbe commented 2 years ago

But i'll try to add support for transformations.
Since zodios advertize zod support, it should handle this use case.
It may not be available a quickly as the other times. So i hope that my previous answer fullfill you current need.

ecyrbe commented 2 years ago

@alex-way fix added, new version v7.1.4