@gorgo/medusa-feed-yandex
Version:
A Medusa plugin that generates a product feed in YML (Yandex Market Language) format
132 lines (120 loc) • 2.98 kB
text/typescript
import { z, ZodEffects, ZodNullable, ZodObject, ZodOptional } from "zod"
/**
* Wraps the original schema to a function to accept and merge
* additional_data schema
*/
export const WithAdditionalData = <T extends ZodObject<any, any>>(
originalSchema: T,
modifyCallback?: (schema: T) => ZodObject<any, any> | ZodEffects<any, any>
) => {
return (
additionalDataValidator?: ZodOptional<ZodNullable<ZodObject<any, any>>>
) => {
let schema: ZodObject<any, any>
if (!additionalDataValidator) {
schema = originalSchema.extend({
additional_data: z.record(z.unknown()).nullish(),
})
} else {
schema = originalSchema.extend({
additional_data: additionalDataValidator,
})
}
return modifyCallback ? modifyCallback(schema as T) : schema
}
}
export const createBatchBody = (
createValidator: z.ZodType,
updateValidator: z.ZodType,
deleteValidator: z.ZodType = z.string()
) => {
return z.object({
create: z.array(createValidator).optional(),
update: z.array(updateValidator).optional(),
delete: z.array(deleteValidator).optional(),
})
}
export const createLinkBody = () => {
return z.object({
add: z.array(z.string()).optional(),
remove: z.array(z.string()).optional(),
})
}
export const createSelectParams = () => {
return z.object({
fields: z.string().optional(),
})
}
export const createFindParams = ({
offset,
limit,
order,
}: {
offset?: number
limit?: number
order?: string
} = {}) => {
const selectParams = createSelectParams()
return selectParams.merge(
z.object({
offset: z.preprocess(
(val) => {
if (val && typeof val === "string") {
return parseInt(val)
}
return val
},
z
.number()
.optional()
.default(offset ?? 0)
),
limit: z.preprocess(
(val) => {
if (val && typeof val === "string") {
return parseInt(val)
}
return val
},
z
.number()
.optional()
.default(limit ?? 20)
),
order: order
? z.string().optional().default(order)
: z.string().optional(),
})
)
}
export const createOperatorMap = (
type?: z.ZodType,
valueParser?: (val: any) => any
) => {
if (!type) {
type = z.string()
}
let simpleType: any = type.optional()
if (valueParser) {
simpleType = z.preprocess(valueParser, type).optional()
}
const arrayType: any = z.array(type).optional()
const unionType: any = z.union([simpleType, arrayType]).optional()
return z.union([
unionType,
z.object({
$eq: unionType,
$ne: unionType,
$in: arrayType,
$nin: arrayType,
$like: simpleType,
$ilike: simpleType,
$re: simpleType,
$contains: simpleType,
$gt: simpleType,
$gte: simpleType,
$lt: simpleType,
$lte: simpleType,
}),
])
}