## Summary
**What** — What changes are introduced in this PR?
Export Zod as a dependency of `@medusajs/framework`.
Closes DX-2414
**Why** — Why are these changes relevant or necessary?
Zod is an essential part of Medusa development. We use it in the core and developers use it in their customizations.
Developers using pnpm won't have access to Zod, as it's not a top-level dependency. While they can install any version, since Zod is an essential aspect of our framework, it's more convenient that we export it and make it accessible to developers.
**How** — How have these changes been implemented?
1. Add Zod as a dependency in `@medusajs/deps` and export it in `@medusajs/framework`
2. Change imports of Zod across projects to import from `@medusajs/framework` and remove the Zod dependency.
> Note: this change doesn't cover admin extensions (and our related packages), as they're not related to the Medusa framework and using Zod in them isn't part of the conventions we document.
Developers can import Zod like this now:
```ts
import { z } from "@medusajs/framework/zod"
```
**Testing** — How have these changes been tested, or how can the reviewer test the feature?
Use the following import in a Medusa project to create an validate zod schemas:
```bash
import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
import { z } from "@medusajs/framework/zod"
export const PostCustomSchema = z.object({
name: z.string(),
})
type PostCustomSchema = z.infer<typeof PostCustomSchema>
export async function POST(
req: MedusaRequest<PostCustomSchema>,
res: MedusaResponse
) {
res.json({
message: `Hello, ${req.validatedBody.name}`
})
}
// in middleware
import { defineMiddlewares, validateAndTransformBody } from "@medusajs/framework/http"
import { PostCustomSchema } from "./admin/custom/route"
export default defineMiddlewares({
routes: [
{
matcher: "/custom",
middlewares: [validateAndTransformBody(PostCustomSchema)],
},
],
})
```
---
## Examples
-
---
## Checklist
Please ensure the following before requesting a review:
- [x] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [ ] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [x] I have linked the related issue(s) if applicable
---
## Additional Context
-
121 lines
4.0 KiB
TypeScript
121 lines
4.0 KiB
TypeScript
import { z } from "@medusajs/framework/zod"
|
|
import {
|
|
applyAndAndOrOperators,
|
|
booleanString,
|
|
} from "../../utils/common-validators"
|
|
import {
|
|
createFindParams,
|
|
createOperatorMap,
|
|
createSelectParams,
|
|
WithAdditionalData,
|
|
} from "../../utils/validators"
|
|
|
|
export const AdminCustomerParams = createSelectParams()
|
|
|
|
export const AdminCustomerGroupInCustomerParams = z.object({
|
|
id: z.union([z.string(), z.array(z.string())]).optional(),
|
|
name: z.union([z.string(), z.array(z.string())]).optional(),
|
|
created_at: createOperatorMap().optional(),
|
|
updated_at: createOperatorMap().optional(),
|
|
deleted_at: createOperatorMap().optional(),
|
|
})
|
|
|
|
export const AdminCustomersParamsFields = z.object({
|
|
q: z.string().optional(),
|
|
id: z
|
|
.union([z.string(), z.array(z.string()), createOperatorMap()])
|
|
.optional(),
|
|
email: z.union([z.string(), z.array(z.string())]).optional(),
|
|
groups: z
|
|
.union([
|
|
AdminCustomerGroupInCustomerParams,
|
|
z.string(),
|
|
z.array(z.string()),
|
|
])
|
|
.optional(),
|
|
company_name: z.union([z.string(), z.array(z.string())]).optional(),
|
|
first_name: z.union([z.string(), z.array(z.string())]).optional(),
|
|
last_name: z.union([z.string(), z.array(z.string())]).optional(),
|
|
has_account: booleanString().optional(),
|
|
created_by: z.union([z.string(), z.array(z.string())]).optional(),
|
|
created_at: createOperatorMap().optional(),
|
|
updated_at: createOperatorMap().optional(),
|
|
deleted_at: createOperatorMap().optional(),
|
|
})
|
|
|
|
export const AdminCustomersParams = createFindParams({
|
|
limit: 50,
|
|
offset: 0,
|
|
})
|
|
.merge(AdminCustomersParamsFields)
|
|
.merge(applyAndAndOrOperators(AdminCustomersParamsFields))
|
|
|
|
export const CreateCustomer = z.object({
|
|
email: z.string().email().nullish(),
|
|
company_name: z.string().nullish(),
|
|
first_name: z.string().nullish(),
|
|
last_name: z.string().nullish(),
|
|
phone: z.string().nullish(),
|
|
metadata: z.record(z.unknown()).nullish(),
|
|
})
|
|
export const AdminCreateCustomer = WithAdditionalData(CreateCustomer)
|
|
|
|
export const UpdateCustomer = z.object({
|
|
email: z.string().email().nullish(),
|
|
company_name: z.string().nullish(),
|
|
first_name: z.string().nullish(),
|
|
last_name: z.string().nullish(),
|
|
phone: z.string().nullish(),
|
|
metadata: z.record(z.unknown()).nullish(),
|
|
})
|
|
export const AdminUpdateCustomer = WithAdditionalData(UpdateCustomer)
|
|
|
|
export const CreateCustomerAddress = z.object({
|
|
address_name: z.string().nullish(),
|
|
is_default_shipping: z.boolean().optional(),
|
|
is_default_billing: z.boolean().optional(),
|
|
company: z.string().nullish(),
|
|
first_name: z.string().nullish(),
|
|
last_name: z.string().nullish(),
|
|
address_1: z.string().nullish(),
|
|
address_2: z.string().nullish(),
|
|
city: z.string().nullish(),
|
|
country_code: z.string().nullish(),
|
|
province: z.string().nullish(),
|
|
postal_code: z.string().nullish(),
|
|
phone: z.string().nullish(),
|
|
metadata: z.record(z.unknown()).nullish(),
|
|
})
|
|
export const AdminCreateCustomerAddress = WithAdditionalData(
|
|
CreateCustomerAddress
|
|
)
|
|
|
|
export const AdminUpdateCustomerAddress = AdminCreateCustomerAddress
|
|
|
|
export const AdminCustomerAddressParams = createSelectParams()
|
|
|
|
export const AdminCustomerAddressesParams = createFindParams({
|
|
offset: 0,
|
|
limit: 50,
|
|
}).merge(
|
|
z.object({
|
|
q: z.string().optional(),
|
|
company: z.union([z.string(), z.array(z.string())]).optional(),
|
|
city: z.union([z.string(), z.array(z.string())]).optional(),
|
|
country_code: z.union([z.string(), z.array(z.string())]).optional(),
|
|
province: z.union([z.string(), z.array(z.string())]).optional(),
|
|
postal_code: z.union([z.string(), z.array(z.string())]).optional(),
|
|
})
|
|
)
|
|
|
|
export type AdminCustomerParamsType = z.infer<typeof AdminCustomerParams>
|
|
export type AdminCustomersParamsType = z.infer<typeof AdminCustomersParams>
|
|
export type AdminCreateCustomerType = z.infer<typeof CreateCustomer>
|
|
export type AdminUpdateCustomerType = z.infer<typeof UpdateCustomer>
|
|
export type AdminCustomerAddressParamsType = z.infer<
|
|
typeof AdminCustomerAddressParams
|
|
>
|
|
export type AdminCreateCustomerAddressType = z.infer<
|
|
typeof CreateCustomerAddress
|
|
>
|