Gathering detailed insights and metrics for @assassinonz/exzodus-client
Gathering detailed insights and metrics for @assassinonz/exzodus-client
Gathering detailed insights and metrics for @assassinonz/exzodus-client
Gathering detailed insights and metrics for @assassinonz/exzodus-client
npm install @assassinonz/exzodus-client
Typescript
Module System
Node Version
NPM Version
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
ExZodus provides a type-safe Axios client wrapper and an Express router with auto-completion features backed by Zod schemas. This project is heavily inspired by the Zodios project.
The existence of this project is due to following factors.
Type instantiation is excessively deep and possibly infinite.ts(2589)
errors.Absolutely not.
If your workflow didn't encounter above mentioned problems, you should definitely use Zodios. It is well documented and established.
Zodios has many more features that won't be included in the scope of this project.
1npm i @assassinonz/exzodus
Use @kubb/swagger-zod
to generate the API schema using an openapi.yaml
file or hand write it.
The API schema is typed as follows.
1type Path = string; 2type Method = string; 3type Api = Record<Path, Record<Method, { 4 request: z.ZodType | undefined; 5 parameters: { 6 path: z.ZodType | undefined; 7 query: z.ZodType | undefined; 8 header: z.ZodType | undefined; 9 }; 10 responses: Record<number | "default", z.ZodType>; 11 errors: Record<number, z.ZodType>; 12}>>;
1export const paths = { 2 "/users/:id": { 3 get: { 4 request: undefined, 5 parameters: { 6 path: z.object({ "id": z.coerce.number.int() }), 7 query: undefined, 8 header: undefined 9 }, 10 responses: { 11 200: z.object({ "id": z.number.int(), "name": z.string() }), 12 404: z.object({ "message": z.string() }) 13 default: z.object({ "id": z.number.int(), "name": z.string() }) 14 }, 15 errors: { 16 404: z.object({ "message": z.coerce.string() }) 17 } 18 }, 19 } 20}
1import { paths } from "../../kubb/zod/operations.js"; 2import { express, ExZodusRouter } from "@assassinonz/exzodus-router"; 3 4//Define extras if modification of request type is needed 5type Extras = { 6 ctx?: { 7 userId: number; 8 } 9} 10 11// @kubb/swagger-zod generated API schema 12// ▼ 13const router = ExZodusRouter.new<typeof paths, Extras>(paths, { 14 //Provide error handler for Zod errors 15 errorHandler: (err, req, res) => { 16 //TODO: Handle errors 17 }, 18 19 //Enable response validation to prevent unintentional data leaks 20 attachResponseValidator: true 21}); 22 23 24// auto-complete path fully typed and validated input params (body, query, params) 25// ▼ ▼ ▼ 26router.get("/users/:id", (req, res) => { 27 if (req.ctx === undefined) { 28 //Allows only documented response codes 29 //Response is typed from the body of 404 response 30 // ▼ 31 return res.status(404).json({ 32 message: "Please login first" 33 }); 34 } else { 35 const user = findUserById(req.ctx.userId); 36 37 //Response is typed from the body of 200 response 38 // ▼ 39 return res.status(200).json({ 40 id: user.id, 41 name: user.name, 42 password: user.password 43 }); 44 } 45 46}); 47 48 49const app = express(); 50app.use(express.json()); 51app.use("/api/v1", router);
Calling this API is now easy and has builtin autocomplete features :
1import { paths } from "../../kubb/zod/operations.js"; 2import { ExZodusClient } from "@assassinonz/exzodus-client"; 3 4 5// @kubb/swagger-zod generated API schema 6// ▼ 7const client = new ExZodusClient(paths, "http://localhost:8080/api/v1"); 8 9 10// typed auto-complete path auto-complete params 11// ▼ ▼ ▼ 12const userResponse = await client.get("/users/:id", { path: { id: 7 } }); 13console.log(userResponse.data);
This should output the following. Note the missing password field due to the attachResponseValidator
option.
1{ 2 id: 7, 3 name: "John Doe" 4}
No vulnerabilities found.
No security vulnerabilities found.