feat(medusa): Improve DX of validators extensions (#4397)
* feat(medusa): Allow to register extended validators seemlesly * Create happy-points-yawn.md * comment
This commit is contained in:
committed by
GitHub
parent
579fcb8cd6
commit
01245ac89e
5
.changeset/happy-points-yawn.md
Normal file
5
.changeset/happy-points-yawn.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
feat(medusa): Allow to register extended validators seemlesly
|
||||
40
packages/medusa/src/utils/__tests__/validator.spec.ts
Normal file
40
packages/medusa/src/utils/__tests__/validator.spec.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { IsString } from "class-validator"
|
||||
import { AdminPostProductsReq as MedusaAdminPostProductsReq } from "../../api/routes/admin/products/create-product"
|
||||
import { registerOverriddenValidators, validator } from "../validator"
|
||||
|
||||
class AdminPostProductsReq extends MedusaAdminPostProductsReq {
|
||||
@IsString()
|
||||
custom_attribute: string
|
||||
}
|
||||
|
||||
describe("Validator", function () {
|
||||
it("should override the original validator", async function () {
|
||||
let err = await validator(MedusaAdminPostProductsReq, {
|
||||
title: "test",
|
||||
})
|
||||
.then(() => void 0)
|
||||
.catch((err) => err)
|
||||
|
||||
expect(err).not.toBeDefined()
|
||||
|
||||
registerOverriddenValidators(AdminPostProductsReq)
|
||||
|
||||
err = await validator(MedusaAdminPostProductsReq, {
|
||||
title: "test",
|
||||
})
|
||||
.then(() => void 0)
|
||||
.catch((err) => err)
|
||||
|
||||
expect(err).toBeDefined()
|
||||
expect(err.message).toEqual("custom_attribute must be a string")
|
||||
|
||||
err = await validator(MedusaAdminPostProductsReq, {
|
||||
title: "test",
|
||||
custom_attribute: "test",
|
||||
})
|
||||
.then(() => void 0)
|
||||
.catch((err) => err)
|
||||
|
||||
expect(err).not.toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -13,3 +13,4 @@ export * from "./product-category"
|
||||
export * from "./remove-undefined-properties"
|
||||
export * from "./set-metadata"
|
||||
export * from "./validate-id"
|
||||
export { registerOverriddenValidators } from "./validator"
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
import { ClassConstructor, plainToInstance } from "class-transformer"
|
||||
import { validate, ValidationError, ValidatorOptions } from "class-validator"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { Constructor } from "@medusajs/types"
|
||||
|
||||
const extendedValidators: Map<string, Constructor<any>> = new Map()
|
||||
|
||||
/**
|
||||
* When overriding a validator, you can register it to be used instead of the original one.
|
||||
* For example, the place where you are overriding the core validator, you can call this function
|
||||
* @example
|
||||
* ```ts
|
||||
* // /src/api/routes/admin/products/create-product.ts
|
||||
* import { registerOverriddenValidators } from "@medusajs/medusa"
|
||||
* import { AdminPostProductsReq as MedusaAdminPostProductsReq } from "@medusajs/medusa/dist/api/routes/admin/products/create-product"
|
||||
* import { IsString } from "class-validator"
|
||||
*
|
||||
* class AdminPostProductsReq extends MedusaAdminPostProductsReq {
|
||||
* @IsString()
|
||||
* test: string
|
||||
* }
|
||||
*
|
||||
* registerOverriddenValidators(AdminPostProductsReq)
|
||||
* ```
|
||||
* @param extendedValidator
|
||||
*/
|
||||
export function registerOverriddenValidators(
|
||||
extendedValidator: Constructor<any>
|
||||
): void {
|
||||
extendedValidators.set(extendedValidator.name, extendedValidator)
|
||||
}
|
||||
|
||||
const reduceErrorMessages = (errs: ValidationError[]): string[] => {
|
||||
return errs.reduce((acc: string[], next) => {
|
||||
@@ -22,6 +50,8 @@ export async function validator<T, V>(
|
||||
plain: V,
|
||||
config: ValidatorOptions = {}
|
||||
): Promise<T> {
|
||||
typedClass = extendedValidators.get(typedClass.name) ?? typedClass
|
||||
|
||||
const toValidate = plainToInstance(typedClass, plain)
|
||||
// @ts-ignore
|
||||
const errors = await validate(toValidate, {
|
||||
|
||||
Reference in New Issue
Block a user