Giter VIP home page Giter VIP logo

zodios's People

Contributors

adipol1359 avatar astahmer avatar ayoubqrt avatar dbanck avatar dependabot[bot] avatar ecyrbe avatar emilpaw avatar g3root avatar ghoullier avatar h-sigma avatar itacirgabral avatar jamesgelok avatar maantje avatar maurer2 avatar pkoo avatar pkrinesh avatar qzcurious avatar renovate-bot avatar renovate[bot] avatar rjwilsondev avatar rmvn27 avatar secondthunder avatar simonflk avatar sunakan avatar thelinuxlich avatar yassh avatar zehir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

zodios's Issues

[improvement] add Alias endpoints

We can improve zodios with named calls in addition to endpoints calls.
Examples:

const client = new Zodios (BASE_URL, [
  {
    method : 'get',
    path: '/users',
    alias: 'getUsers',
    parameters: [...]
  }
  ]);

Then we could call it like that:

  client.get('/users');

Or with it's alias :

  client.getUsers();

[zodios-openapi] multi security schemes

Zodios should allow to declare multiple security schemes for openapi

We could add something like this :

const document = toMultiSchemeOpenApi({
  info: {
    title: 'Project A API',
    version: '0.0.0',
    description: 'A simple example API',
  },
  servers: [
    {
      url: '/',
    },
  ],
  securitySchemeAPIs: [
    {
      name: 'basic',
      securityScheme: basicAuthScheme(),
      api: basicAuthAPI,
    },
    {
      name: 'bearer',
      securityScheme: bearerAuthScheme(),
      api: bearerAuthAPI,
    },
    {
        api: notSecuredAPI, // for health check, etc
    }
  ] 
});

Validating request but not response ?

Currently we can validate both the request payload sent and the response content using validate or none

Continuing my reasoning (and use-cases for openapi-zod-client) that not all APIs are in our own control, and therefore that we can only control what we send in the request payload,

would you consider having a validate mode (as a string enum ?) with the current boolean ?

something like:
validate: "request" | "response" | boolean

tbh I don't know if a response mode would really be useful but I added it in the example above so that every options are available

Path parameters with explicit types are not correct at runtime

If I have the following API and endpoint:

const userApi = makeApi([
  {
    method: 'get',
    path: '/users/:id',
    alias: 'getUser',
    description: 'Get a user',
    parameters: [
      {
        name: 'id',
        type: 'Path',
        schema: z.number(),
      },
    ],
    response: z.object({
      id: z.number(),
      name: z.string().nullable(),
    }),
    errors,
  },
]);

const userRouter = ctx.router(userApi);

userRouter.get('/users/:id', async (req, res) => {
  console.log(typeof req.params.id);

  return res.json({
    id: req.params.id,
    name: "example",
  });
});

The output of the console.log() is string, even though the type is inferred as number.

Make zodiosApp and ZodiosRouter context aware

Express does not have a context per say.
Users usually use req object and inject their context in there.
Since zodios is aimed at typesafety and discoverability, we should add one.

const context = z.object({
   user: z.object({
     name: z.string(),
     email: z.string().email(),
   })
});

const app = zodiosApp(userApi, { context });

app.get('/users', (req, res) => {
  // user is typed and req has autocompletion
  const user = req.user;
  if (isAdmin(user)) {
    res.status(403).json (...);
  }
  ...
});

Transforming parameters causes incorrect type to be inferred

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?

[Feature Request] useQuery for POST request

Senario

For my experience, it quite often to use a POST request for searching resource or pagination.
For example:

POST /users/search HTTP/1.1
Accept: application/json
Content-Type: application/json

{
  "gender": "female",
  "limit": 20
}

Proposal

Maybe it could be

export const Request = z.object({
  gender: z.enum(["male", "female"]),
  limit: z.number().min(0).max(200),
});

export const Response = z.object({});

export type User = z.infer<typeof Request>;

export const userApi = makeApi([
  {
    method: "post",
    mutation: false, // <-- explicitly make it useQuery-able
    path: "users/search",
    parameters: [
      {
        name: "body",
        type: "Body",
        schema: Request,
      },
    ],
    response: Response,
  },
]);

[Feature Request] - Improve Error messages

I'm really liking this library so far. For context I'm creating a web app which acts essentially as an aggregator for other API's and Zodios is doing a lot of the heavy lifting for me, so firstly thank you! ๐Ÿ˜

I've noticed that the error's that are reported from a failed response parsing are just throwing the ZodError, without any further context.

ZodError: [
  {
    "code": "invalid_type",
    "expected": "array",
    "received": "undefined",
    "path": [
      "value"
    ],
    "message": "Required"
  }
]

My ideal solution would give additional context, such as the URL called with an option to enable the original response content to be shown. It may be possible/more suitable for this functionality to live inside a plugin, which I'll start to investigate if it's possible to do so now. Thought I would just get the ball rolling, in the case where this is actually a lot simpler than it seems.

[Bug] select for QueryObserverOptions is typed incorrectly

The typing of select was introduced due to #158

For convenience, a codesandbox to demo the bug here.

The bug is described by comments of following code block

const { data } = apiHook.useUser(undefined, {
  //    ^^^^
  //    data is NOT reflecting to return type of select
  select:
    // ^^ zodios is forcing me follow the type Response
    () => ({
      first_name: "first"
    })
});

function useUser() {
  const { data } = useQuery(["key"], () => ({ name: "name" }), {
    // ^^^^
    // data is reflected to return type of select
    // typed as {
    //   first_name: string;
    // } | undefined
    select: () => ({ first_name: "first" })
  });
}

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v4
  • actions/setup-node v4
  • actions/checkout v4
  • github/codeql-action v2
  • github/codeql-action v2
.github/workflows/publish.yml
  • actions/checkout v4
  • actions/setup-node v4
  • orhun/git-cliff-action v2
  • actions/create-release v1
npm
package.json
  • @jest/types 29.6.3
  • @types/express 4.17.19
  • @types/jest 29.5.5
  • @types/multer 1.4.8
  • @types/node 20.8.9
  • axios 1.5.1
  • express 4.18.2
  • form-data 4.0.0
  • jest 29.7.0
  • multer 1.4.5-lts.1
  • rimraf 5.0.5
  • ts-jest 29.1.1
  • ts-node 10.9.1
  • typescript 5.2.2
  • zod 3.22.4
  • axios ^0.x || ^1.0.0
  • zod ^3.x

  • Check this box to trigger a request for Renovate to run again on this repository

zodios cause big bundle size (on nextjs)

Discussed in #197

Originally posted by QzCurious October 21, 2022
I'm not familiar how bundler works and how to trace it down. I am willing to inspect it more, please give me some instructions.

The problem

I'm using nextjs. When integrate with zodios, a simple request can cause build bundle up to 197KB. Although @zodios/core is only of size 3.7 kb. I don't know if it's me importing thing wrong. Please explain to me what is causing this to be happend.
image

Here is a repo to showcase. Each commit take a small step for reviewing how code and bundle size changes. I've also configured it with @next/bundle-analyzer so you can ANALYZE=true yarn build to inspect the bundle (but I can't tell how and what is wrong, sadly).

In summary:

clean page with axios with zod with zodios
77.9 kB 95.3 kB 106 kB 197 kb

One wierd thing I noticed. bundle-analyzer list out a few packages that is not mean to be ship to production are included in bundle.
image

React hook can not be auto-completed

Problem

A sample codesandbox for demonstrating the bug
image

And note that, following the doc, I installed @tanstack/react instead of react-query.

Possible Solution

A simple solution is to install react-query@3.

But maybe this library should use @tanstack/react instead.
image

Sorry I can't locate the right spot for the breaking code. And also, I can't figure out how this library were importing react-query. It's even not marked as a dependency in package.json. Hope the provided information is enough.

Cryptic error message

When the error sent by a API request doesn't conform to the defined schema, Zodios replies just with Zodios: Invalid response, there should be a description of what's missing and what it's receiving

API shorthand definition

I feel like the API for declaring parameters could be simplified, it seems a bit verbose:

apiBuilder({
  path: '/marketplaces/:id/transactions',
  method: 'get',
  alias: 'getMarketplaceTransactions',
  // if it were a POST
  body: {
    .....
  },
  queries: {
      limit: z.number().optional()
      offset: z.number().optional()
      'date_range[gte]': z.string().optional()
      'date_range[lte]': z.string().optional()
  },
  headers: {
    Authorization: z.string()
  },
  // if the user really wants description for openAPI:
  description: {
     queries: {
        limit: 'A parameter to limit the number of rows returned'
     }
  },
  response: transactionsSchema,
})

Besides being less verbose, the parameter types have the same name as the objects in the API client (queries, headers) so it's intuitive

Function to create a single endpoint definition

We currently have an file with a bunch of route definitions. The readability really starts to get worse as the file grow, having an makeEndpoint method would be specially useful when we want one definition per file, e.g:

// getUser.ts

export default makeEndpoint({
  method: "get",
  path: "/users/:id",
  alias: "getUser",
  description: "Get a user",
  response: z.object({
    id: z.number(),
    name: z.string(),
  }),
})
// createUser.ts

export default makeEndpoint({
  method: "post",
  path: "/users",
  alias: "createUser",
  description: "Create a user",
  parameters: [{
    name: 'body',
    type: 'Body',
    schema: z.object({
      name: z.string(),
    })
  }],
  response: z.object({
    id: z.number(),
    name: z.string(),
  }),
})
// api.ts
import getUser from './getUser';
import createUser from './createUser';

// It could also be compatible `makeApi` as well.
const api = new Zodios([getUser, createUser])

Query string as an array

Thanks for a great library! I really like it.
I've been working with API which requires passing an array of IDs.
for example:

  {
    method: 'get',
    path: '/users',
    alias: 'getUsers',
    parameters: [
      {
        type: 'Query',
        name: 'id',
        schema: z.array(z.string()),
      },
    ],
    response: z.array(z.object(...)),
  })

currently, zodios generates following URL:

http://localhost/users?id=1,2,3

however, the standard URL API does not recognize it as an array

> new URL('http://localhost/users?id=1,2,3').searchParams.getAll('id')
['1,2,3']

I think the standard representation of an array of searchparams would be:

http://localhost/users?id=1&id=2&id=3
> new URL('http://localhost/users?id=1&id=2&id=3').searchParams.getAll('id')
['1', '2', '3']

can I change the encoding of an array?

Ability to provide default values for params/queries

This is something I have wanted to be able to do a few times now and doesn't seem possible. Could be solved via the Zod default function if all the params/query fields were parsed with the schema (I don't see that happening anywhere but maybe I missed it), that's what I have tried so far.

[Feature Request] Allow GET request with body

The data parameter of axios is omitted from get method by ZodiosRequestOptionsByPath.

Note: Sending body/payload in a GET request may cause some existing implementations to reject the request โ€” while not prohibited by the specification, the semantics are undefined. It is better to just avoid sending payloads in GET requests.
MDN

Could zodios be less opinionated about it?

Typescript-json > zod ?

There is a new player in the field of TS runtime validation libraries. typescript-json adds a plugin transform to tsconfig.json and can work with existing TS types.

Pros

  • No need to add a extra DSL for runtime, just use the TS interfaces/types
  • Supports anything fancy in TS level
  • Much faster than zod
  • Has a "comment tag" API for richer validation
  • Might simplify zodios internals

Cons

  • Doesn't have transforms
  • Zod has better error output

I understand the library is deeply committed to zod but anyway I thought it would be interesting to share this, might be gamechanging.

Inject default params in Zodios client

Suppose I have a url like https://endpoint.com/:id/transactions and I will always pass the same id. Is it possible to inject this parameter on the client so I don't need to add it to the call everytime and make the typechecker happy?

If all fields in a schema are optional, the parameter should be too

I have a parameter defined as

{
      name: 'querystring',
      type: 'Query',
      schema: z.object({
        limit: z.number().optional(),
        offset: z.number().optional(),
        'date_range[gte]': z.string().optional(),
        'date_range[lte]': z.string().optional(),
      }),
    }

If I don't pass { queries: {querystring: {}} to the API call the typechecker will complain.

make config parameter read-only

Hi, query string as an array again!
I'm useing Zodios with a GraphQL DataLoader.

example:

const userResponse = z.array(
  z.object({
    id: z.number(),
    name: z.string(),
  })
}),

type UserResponse = z.infer<typeof userResponse>

const apiClient = new Zodios(
  "https://example.com",
  [
    {
      method: "get",
      path: "/users",
      alias: "getUsers",
      parameters: [
        {
          type: 'Query',
          name: 'keys',
          schema: z.array(z.string()).min(1),
        },
      ],
      response: userResponse,
    },
  ],
);

const loader = new DataLoader<string, UserResponse>(
  async function batchFunction(keys) { // keys: readonly string[]
    const response = await apiClient.getUsers({ queries: { keys: keys as string[]} })
    ...
  }
)

It's works very well but unfortunately it needs cast because a DataLoader passes a readonly array.
I don't think Zodios will change the passed config (In fact, Zodios internally casts them as read-only.), so could you concider adding readonly to the config parameter deeply?
(Probably the same for the body parameter of the post method, etc.)

Some strict TS narrowing is limiting parameter reuse

If we define the parameters array outside of the parameter definition like this:

apiBuilder({
  path: '/marketplaces/:id/transactions',
  method: 'get',
  alias: 'getTransactions',
  parameters: queryStringStandardParameters,
  response: transactionsSchema,
})

The typechecker complains with:
image

Subscriptions through SSE

To keep things simple, as of today most browser support HTTP 2, so SSE doesn't have those disadvantages of the past and can replace Websockets anywhere you aren't building a FPS-shooter on the browser :)

So it's a simpler architecture and built upon HTTP already. Some GraphQL projects are already adopting SSE as the standard for subscriptions, like graphql-yoga for example.

What do you think?

Using multiple query parameters in an endpoint

Hello and thanks for this great library!

I have a question that I haven't been able to resolve, maybe there is a solution but I missed it in the docs and couldn't find an answer through Google/Stackoverflow either.

Let's say I have a GET endpoint that requires multiple query parameters in the request. How can I implement this with zodios?

{
  method: "get",
  path: "/users/:id", // id here is a single optional parameter
  alias: "getUser",
  description: "Get a user",
  response: z.object({
    id: z.number(),
    name: z.string(),
  })
}

But my endpoint is using multiple parameters like so: /users?page=1&pageSize=10&name=test

How can I add these parameters and type them as I want? I fiddled around and couldn't make it work with multiple parameters like /users?page=:page&pageSize=:pageSize&name=:name. I also want to type these input parameters.

Feature Request: Allow BaseUrl to be optional

This is a feature request to allow the BaseUrl to be optional when initialising Zodios.

The reason for this is that I want to have use a relative path, instead of an absolute path to fetch data from the web server the app is running under (As I'll be running zodios in the browser).

bug: makeApi not working as intended?

I'm not sure what I'm doing wrong, but I'm only getting types coming through when I use the apiBuilder helper, but if I use makeApi the types look messed up, see the screenshot below. Is this a bug or am I not using makeApi as intended?

image

[Feature Request] Validation on path parameters

Discussed in #176

Originally posted by epotter2297 October 11, 2022
It would be really cool if there was a way to use zod to validate my path parameters. For example, if I have an endpoint like so:

{
    method: 'get',
    path: '/users/:id',
    alias: 'getUser',
    description: 'Get a user',
    response: z.object({
      id: z.number(),
      name: z.string().nullable(),
    }),
},

And I want to make sure that id is a valid UUID, I could do something like:

{
    method: 'get',
    path: '/users/:id',
    alias: 'getUser',
    description: 'Get a user',
    parameters: [
      {
        name: 'id',
        description: 'The user id',
        type: 'Path',
        schema: z.string().uuid(),
      },
    ],
    response: z.object({
      id: z.number(),
      name: z.string().nullable(),
    }),
},
```</div>

[Bug] `data` for POST request is optional

I've define a body parameter for my post request. But I can ignore data without ts showing error.

codesandbox

import { makeApi, Zodios } from "@zodios/core";
import { z } from "zod";

export const Request = z.object({
  page: z.number().int().min(1),
  perpage: z.number().int().max(20)
});

const Response = z.object({});

const userApi = makeApi([
  {
    method: "post",
    path: "user/list",
    alias: "userList",
    immutable: true,
    parameters: [
      {
        name: "body",
        type: "Body",
        schema: Request
      }
    ],
    response: Response
  }
]);

const apiClient = new Zodios(userApi);
apiClient.userList(); // <-- data should be required
apiClient.post("user/list"); // <-- data should be required

Usage without Axios

Hey @ecyrbe, this is fantastic!

In my org, we recently moved off axios and started using a small custom fetch-wrapper. We really want to use this but we don't want to go back to axios. It would be awesome if we could provide a custom fetcher to this lib. Is this something you may consider?

I understand if this is out-of-scope for this lib.

Thanks!!

missing TS error when a required query param is not passed

idk if that is even possible but I expected this error at compile-time

const apiEndpoints = makeApi([
  {
    method: 'delete',
    path: '/cart/clean',
    requestFormat: 'json',
    parameters: [
      {
        name: 'storeId',
        type: 'Query',
        schema: z.number(),
      },
    ],
    response: z.string(),
  },
]);
const client = new Zodios(apiEndpoints);

// no error, should have error
client.delete('/cart/clean');

// no error, should have error
client.delete('/cart/clean', undefined);

// expects error, is fine
client.delete('/cart/clean', undefined, {});

// expects error, is fine
client.delete('/cart/clean', undefined, { queries: {} });

I think there is the same behaviour with header params

Improve API definition creation experience

One of the good ideas of zodios is to use plain objects to declare APIs.
This make api definition easier to read, faster to write. But it comes at a cost :

  • A lot of typescript utility types had to be made to parse the definition and transform it.
  • When you have made a mistake typescript create cryptic messages for your whole definition instead of highlighting where the error is.
  • Autocompletion is somewhat broken sometimes (all optional properties don't seem to have autocompletion once one endpoint has been written)

Needs investigation to improve this and maybe simplify the whole thing if possible

[Improvement] add CRUD generation helper

We could improve zodios with CRUD generation feature to remove unnecessary duplicated declarations :

client = new Zodios(BASE_URL, 
  CRUD('users', { schema: zodUserSchema }));

Plugin application order inconsistent

I'm seeing an issue where the plugins are applied in one order for 2 requests and then in a different order after that, leading to problems with a plugin that modifies the API response before it reaches the zod validation plugin. So the first 2 requests fail and then the 3rd succeeds because the response transform plugin is now processed before the zod validation plugin.

It seems to be because of this in-place reverse happening here https://github.com/ecyrbe/zodios/blob/main/src/plugins/zodios-plugins.ts#L111

If I locally change that to [...this.plugins].reverse() the problem goes away. Using v9.3.1 of @zodios/core.

P.S. Love the library so far, building an Observable variant of the zodios hooks package to use with XState ontop of @tanstack/query-core

[Feature Request] - Infer from Alias/Path

๐Ÿ‘‹ Hello, it's me again!

What do you think on adding a helper function which can infer the response shape of an alias?

For example I have the following client configured:

export const client = new Zodios("https://example.com", [
  {
    method: 'get',
    path: '/api/get_thing',
    alias: 'getThings',
    response: z.object({
      result: z.string()
    })
  },
] as const);

It would be really cool if we could do something like the following:

import { InferResponse } from "@Zodios/core";

type getThingsResponse = InferResponse<"getThings">
// { result: string; }

This is very similar to the following: https://trpc.io/docs/infer-types

The reason I ask for this is because I'm using SvelteKit and right now the typing between the backend and frontend isn't that strong, so I have to extract my types/schemas into a separate file and import into both places which works but isn't as smooth as I'd like ๐Ÿ˜„

API Client-wide variable in method path

Hi there! First, I'd like to thank you for this library. I have been using it for some time and I love it!

I have been working with API, which requires passing an Organization ID within the endpoint path, for example:

/v1/organizations/**organization_id**/shipments

Is it possible to set that ID globally for API client instance? I would prefer to avoid passing it in every operation as variable.

Thanks!

Dynamic base URL using plugin

Hey, I have a use-case where I need to inject a custom base URL depending on the request config, to do so i'm currently using a plugin creator (the baseUrl is an env var fetched at runtime and dynamic by country to be specific..)

it looks kind of like this:

const endpoints = makeApi([
  {
    method: 'get',
    path: '/v1/stores/:store_id',
    requestFormat: 'json',
    response: variables.d,
  },
  {
    method: 'get',
    path: '/v2/customer/:customer_id',
    requestFormat: 'json',
    response: variables.d,
  },
]);
// no baseUrl provided since it's only known at runtime
export const api = new Zodios(endpoints);

// ...
const createApiPlugin = (apiId: ApiId) => {
  return {
    name: 'apiPlugin',
    request: async (_endpoint, config) => {
      const state = xxx;
      const baseUrl = xxx[apiId];
      return { ...config, url: `${baseUrl}${config.url}` };
    }
  }
}

but then I get an error because the endpoint is not found in the response

would it be ok to allow overriding a baseUrl in the return of the plugin.request rather than overriding url completely ? i think this would solve my use-case and would not break anything

some utilities are no longer visible

Hi, I've created a Zodios client plugin which uses the following utilities:

import { findEndpoint } from '@zodios/core/lib/plugins/zodios-plugins.utils'
import { replacePathParams } from '@zodios/core/lib/utils'

It worked fine until v10.2.0, however since v10.3.0 these utilities are no longer visible.
These may not have been intended to be public APIs, but I think they are very useful.

Is it possible to use these utilities in a custom plugins? Or is there an alternative?

headers object doesn't accept the defined schema

I have a parameter with the Header type defined as:

{
  type: 'Header',
  name: 'token',
  schema: z.object({
    Authorization: z.string().transform(s => {
      return `Basic ${Buffer.from(s + ':').toString('base64')}`
    }),
  }),
}

But when I try to use it like this:

zoop.getMarketplaceTransactions({
  params: { id: marketplace_id },
  headers: {
    token: {
      Authorization: key,
    },
  },
})

The typechecker complains about the object shape:
image

Ability to have multiple aliases with different schemas for the same endpoint

Hi! ๐Ÿ‘‹

Firstly, amazing project - one of the best typed libraries I've seen.

I have a small improvement suggestion - would be great, if the Zod validation utility searching for schema to apply to the response took into account also the alias name, not just the method with the path. This would allow forming multiple endpoint descriptions for the same endpoint, for which developer expects to receive different results (e.g. depending on type of entity returned).

Sample use case
The GET /vehicle/:id/state endpoint returns a vehicle that can be of different types (either a car, or a ship, or a bike) and so the responses would be different too (1st would return fields like consumedGas, 2nd: isSailFolded, etc.). While it's possible to create a schema with discriminated union for those, it might end up to be a big union. Also, in some cases, knowing the context of the query, it might make sense for it to only return one of the vehicle types (e.g. a dashboard panel displaying tire pressure wouldn't be satisfied with ship vehicle being returned). For such situations, a developer might create endpoint descriptions for the same endpoint, but with different response validation schemas and of course different aliases: getCarState, getShipState, etc.


I used patch-package to fast-forward this functionality locally, and it works perfectly - here's the code for the core and react packages:

diff --git a/node_modules/@zodios/core/lib/plugins/zod-validation.plugin.js b/node_modules/@zodios/core/lib/plugins/zod-validation.plugin.js
index 2578894..c10620e 100644
--- a/node_modules/@zodios/core/lib/plugins/zod-validation.plugin.js
+++ b/node_modules/@zodios/core/lib/plugins/zod-validation.plugin.js
@@ -48,7 +48,7 @@ const plugin = {
         return conf;
     }),
     response: (api, config, response) => __awaiter(void 0, void 0, void 0, function* () {
-        const endpoint = (0, zodios_plugins_utils_1.findEndpoint)(api, config.method, config.url);
+        const endpoint = (0, zodios_plugins_utils_1.findEndpoint)(api, config.method, config.url, config.fromAlias);
         /* istanbul ignore next */
         if (!endpoint) {
             throw new Error(`No endpoint found for ${config.method} ${config.url}`);
diff --git a/node_modules/@zodios/core/lib/plugins/zodios-plugins.utils.js b/node_modules/@zodios/core/lib/plugins/zodios-plugins.utils.js
index ba5828e..478af9c 100644
--- a/node_modules/@zodios/core/lib/plugins/zodios-plugins.utils.js
+++ b/node_modules/@zodios/core/lib/plugins/zodios-plugins.utils.js
@@ -1,7 +1,7 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.findEndpoint = void 0;
-function findEndpoint(api, method, path) {
-    return api.find((e) => e.method === method && e.path === path);
+function findEndpoint(api, method, path, alias) {
+    return api.find((e) => e.method === method && e.path === path && (alias === undefined || e.alias === alias));
 }
 exports.findEndpoint = findEndpoint;
diff --git a/node_modules/@zodios/core/lib/zodios.js b/node_modules/@zodios/core/lib/zodios.js
index 4190f45..5784163 100644
--- a/node_modules/@zodios/core/lib/zodios.js
+++ b/node_modules/@zodios/core/lib/zodios.js
@@ -137,10 +137,10 @@ class ZodiosClass {
         this.api.forEach((endpoint) => {
             if (endpoint.alias) {
                 if (["post", "put", "patch", "delete"].includes(endpoint.method)) {
-                    this[endpoint.alias] = (data, config) => this.request(Object.assign(Object.assign({}, config), { method: endpoint.method, url: endpoint.path, data }));
+                    this[endpoint.alias] = (data, config) => this.request(Object.assign(Object.assign({}, config), { method: endpoint.method, url: endpoint.path, data }, { fromAlias: endpoint.alias }));
                 }
                 else {
-                    this[endpoint.alias] = (config) => this.request(Object.assign(Object.assign({}, config), { method: endpoint.method, url: endpoint.path }));
+                    this[endpoint.alias] = (config) => this.request(Object.assign(Object.assign({}, config), { method: endpoint.method, url: endpoint.path }, { fromAlias: endpoint.alias }));
                 }
             }
         });
diff --git a/node_modules/@zodios/react/lib/hooks.js b/node_modules/@zodios/react/lib/hooks.js
index 8959b82..ceb8f0b 100644
--- a/node_modules/@zodios/react/lib/hooks.js
+++ b/node_modules/@zodios/react/lib/hooks.js
@@ -26,11 +26,11 @@ var ZodiosHooksClass = /** @class */ (function () {
             if (endpoint.alias) {
                 if (["post", "put", "patch", "delete"].includes(endpoint.method)) {
                     _this["use".concat((0, utils_1.capitalize)(endpoint.alias))] = function (config, mutationOptions) {
-                        return _this.useMutation(endpoint.method, endpoint.path, config, mutationOptions);
+                        return _this.useMutation(endpoint.method, endpoint.path, { ...config, fromAlias: endpoint.alias }, mutationOptions);
                     };
                 }
                 else {
-                    _this["use".concat((0, utils_1.capitalize)(endpoint.alias))] = function (config, queryOptions) { return _this.useQuery(endpoint.path, config, queryOptions); };
+                    _this["use".concat((0, utils_1.capitalize)(endpoint.alias))] = function (config, queryOptions) { return _this.useQuery(endpoint.path, { ...config, fromAlias: endpoint.alias }, queryOptions); };
                 }
             }
         });

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.