@zodyac/zod-mongoose 1.1.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { zm } from \"./mongoose.types.js\";\nimport { Schema, SchemaTypes, Types, isValidObjectId } from \"mongoose\";\nimport {\n ZodAny,\n ZodArray,\n ZodBoolean,\n ZodDate,\n ZodDefault,\n ZodEffects,\n ZodEnum,\n ZodNullable,\n ZodNumber,\n ZodObject,\n ZodOptional,\n ZodRawShape,\n ZodString,\n ZodType,\n ZodUnion,\n z,\n} from \"zod\";\n\n/**\n * Converts a Zod schema to a Mongoose schema\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { zId, zodSchema } from '@zodyac/zod-mongoose';\n * import { model } from 'mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: zId.describe('ObjectId:Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const schema = zodSchema(zDoc);\n * const userModel = model('User', schema);\n */\nexport function zodSchema<T extends ZodRawShape>(\n schema: ZodObject<T>,\n): Schema<z.infer<typeof schema>> {\n const definition = parseObject(schema);\n return new Schema<z.infer<typeof schema>>(definition);\n}\n\n/**\n * Converts a Zod schema to a raw Mongoose schema object\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { zId, zodSchemaRaw } from '@zodyac/zod-mongoose';\n * import { model, Schema } from 'mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: zId.describe('ObjectId:Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const rawSchema = zodSchemaRaw(zDoc);\n * const schema = new Schema(rawSchema);\n * const userModel = model('User', schema);\n */\nexport function zodSchemaRaw<T extends ZodRawShape>(\n schema: ZodObject<T>,\n): zm._Schema<T> {\n return parseObject(schema);\n}\n\n/**\n * Zod ObjectId type\n *\n * You can provide a reference to a model to enable population via zod .describe() method.\n * Description must start with 'ObjectId:' followed by the collection name.\n *\n * Can also be used for string validation for ObjectId.\n *\n * @example\n * import { zId } from '@zodyac/zod-mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * companyId: zId.describe('ObjectId:Company'),\n * });\n */\nexport const zId = z\n .string()\n .refine((v) => isValidObjectId(v), { message: \"Invalid ObjectId\" })\n .or(z.instanceof(Types.ObjectId).describe(\"ObjectId\"));\n\n/**\n * Zod UUID type (experimental)\n *\n * Use with caution.\n *\n * You can provide a reference to a model to enable population via zod .describe() method.\n * Description must start with 'UUID:' followed by the collection name.\n *\n * Can also be used for string validation for UUID.\n *\n * @warning\n * This is an expreimental feature.\n * UUIDs in Mongoose are a bit of a pain.\n * Mongoose uses version 4 UUIDs, which may not be compatible with the UUIDs used in other languages, e.g. C#.\n *\n * @example\n * import { zUUID, zodSchema } from '@zodyac/zod-mongoose';\n * import { z } from 'zod';\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * wearable: zUUID.describe('UUID:Wearable'),\n * });\n */\nexport const zUUID = z\n .string()\n .uuid({ message: \"Invalid UUID\" })\n .or(z.instanceof(Types.UUID).describe(\"UUID\"));\n\n// Helpers\nfunction parseObject<T extends ZodRawShape>(obj: ZodObject<T>): zm._Schema<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const object: any = {};\n for (const [key, field] of Object.entries(obj.shape)) {\n if (field instanceof ZodObject) {\n object[key] = parseObject(field);\n } else {\n const f = parseField(field);\n if (f) object[key] = f;\n else\n console.error(\n `Key ${key}: Unsupported field type: ${field.constructor}`,\n );\n }\n }\n return object;\n}\n\nfunction parseField<T>(\n field: ZodType<T>,\n required?: boolean,\n def?: T,\n // validate?: (v: T) => boolean,\n): zm.mField | null {\n if (field instanceof ZodObject) {\n return parseObject(field);\n }\n\n if (field instanceof ZodNumber) {\n return parseNumber(\n field,\n required,\n def as number,\n field.description?.toLocaleLowerCase() === \"unique\",\n // validate as (v: number) => boolean,\n );\n }\n\n if (field instanceof ZodString) {\n return parseString(\n field,\n required,\n def as string,\n field.description?.toLocaleLowerCase() === \"unique\",\n // validate as (v: string) => boolean,\n );\n }\n\n if (field instanceof ZodEnum) {\n return parseEnum(Object.keys(field.Values), required, def as string);\n }\n\n if (field instanceof ZodBoolean) {\n return parseBoolean(required, def as boolean);\n }\n\n if (field instanceof ZodDate) {\n return parseDate(required, def as Date);\n }\n\n if (field instanceof ZodArray) {\n return [parseField(field.element)];\n }\n\n if (field instanceof ZodDefault) {\n return parseField(\n field._def.innerType,\n required,\n field._def.defaultValue(),\n );\n }\n\n if (field instanceof ZodOptional) {\n return parseField(field._def.innerType, false, undefined);\n }\n\n if (field instanceof ZodNullable) {\n return parseField(field._def.innerType, false, def || null);\n }\n\n if (field.description?.startsWith(\"ObjectId\")) {\n const ref = field.description.split(\":\")[1];\n if (ref) return parseObjectIdRef(required, ref);\n return parseObjectId(required);\n }\n\n if (field.description?.startsWith(\"UUID\")) {\n const ref = field.description.split(\":\")[1];\n if (ref) return parseUUIDRef(required, ref);\n return parseUUID(required);\n }\n\n if (field instanceof ZodUnion) {\n return parseField(field._def.options[0]);\n }\n\n if (field instanceof ZodAny) {\n return parseMixed(required, def);\n }\n\n if (field instanceof ZodEffects) {\n if (field._def.effect.type === \"refinement\") {\n return parseField(\n field._def.schema,\n required,\n def,\n // field._def.effect.refinement as (v: T) => boolean,\n );\n }\n }\n return null;\n}\n\nfunction parseNumber(\n field: ZodNumber,\n required: boolean = true,\n def?: number,\n unique: boolean = false,\n validate?: (v: number) => boolean,\n): zm.mNumber {\n if (validate) {\n return {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n validation: {\n validate,\n },\n required,\n unique,\n };\n }\n\n return {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n required,\n unique,\n };\n}\n\nfunction parseString(\n field: ZodString,\n required: boolean = true,\n def?: string,\n unique: boolean = false,\n validate?: ((v: string) => boolean) | undefined,\n): zm.mString {\n if (validate) {\n return {\n type: String,\n default: def,\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n validation: {\n validate,\n },\n unique,\n };\n }\n\n return {\n type: String,\n default: def,\n // TODO: match: field.regex(),\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n unique,\n };\n}\n\nfunction parseEnum(\n values: string[],\n required: boolean = true,\n def?: string,\n): zm.mString {\n return {\n type: String,\n default: def,\n enum: values,\n required,\n unique: false,\n };\n}\n\nfunction parseBoolean(required: boolean = true, def?: boolean): zm.mBoolean {\n return {\n type: Boolean,\n default: def,\n required,\n };\n}\n\nfunction parseDate(required: boolean = true, def?: Date): zm.mDate {\n return {\n type: Date,\n default: def,\n required,\n };\n}\n\nfunction parseObjectId(required: boolean = true): zm.mObjectId {\n return {\n type: SchemaTypes.ObjectId,\n required,\n };\n}\n\nfunction parseObjectIdRef(required: boolean = true, ref: string): zm.mObjectId {\n return {\n type: SchemaTypes.ObjectId,\n ref,\n required,\n };\n}\n\nfunction parseUUID(required: boolean = true): zm.mUUID {\n return {\n type: SchemaTypes.UUID,\n required,\n };\n}\n\nfunction parseUUIDRef(required: boolean = true, ref: string): zm.mUUID {\n return {\n type: SchemaTypes.UUID,\n ref,\n required,\n };\n}\n\nfunction parseMixed(\n required: boolean = true,\n def?: unknown,\n): zm.mMixed<unknown> {\n return {\n type: SchemaTypes.Mixed,\n default: def,\n required,\n };\n}\n\nexport default zodSchema;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/extension.ts"],"sourcesContent":["import { Schema, type SchemaOptions, SchemaTypes } from \"mongoose\";\nimport {\n ZodArray,\n ZodDate,\n ZodDefault,\n ZodEffects,\n ZodEnum,\n ZodMap,\n ZodNullable,\n ZodNumber,\n ZodObject,\n ZodOptional,\n type ZodRawShape,\n ZodRecord,\n ZodString,\n type ZodType,\n ZodUnion,\n type z,\n} from \"zod\";\nimport type { zm } from \"./mongoose.types.js\";\nexport * from \"./extension.js\";\n\n/**\n * Converts a Zod schema to a Mongoose schema\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { extendZod, zodSchema } from '@zodyac/zod-mongoose';\n * import { model } from 'mongoose';\n * import { z } from 'zod';\n *\n * extendZod(z);\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: z.objectId('Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const schema = zodSchema(zDoc);\n * const userModel = model('User', schema);\n */\nexport function zodSchema<T extends ZodRawShape>(\n schema: ZodObject<T>,\n options?: SchemaOptions<any>, // TODO: Fix any\n): Schema<z.infer<typeof schema>> {\n const definition = parseObject(schema);\n return new Schema<z.infer<typeof schema>>(definition, options);\n}\n\n/**\n * Converts a Zod schema to a raw Mongoose schema object\n * @param schema zod schema to parse\n * @returns mongoose schema\n *\n * @example\n * import { extendZod, zodSchemaRaw } from '@zodyac/zod-mongoose';\n * import { model, Schema } from 'mongoose';\n * import { z } from 'zod';\n *\n * extendZod(z);\n *\n * const zUser = z.object({\n * name: z.string().min(3).max(255),\n * age: z.number().min(18).max(100),\n * active: z.boolean().default(false),\n * access: z.enum(['admin', 'user']).default('user'),\n * companyId: z.objectId('Company'),\n * address: z.object({\n * street: z.string(),\n * city: z.string(),\n * state: z.enum(['CA', 'NY', 'TX']),\n * }),\n * tags: z.array(z.string()),\n * createdAt: z.date(),\n * updatedAt: z.date(),\n * });\n *\n * const rawSchema = zodSchemaRaw(zDoc);\n * const schema = new Schema(rawSchema);\n * const userModel = model('User', schema);\n */\nexport function zodSchemaRaw<T extends ZodRawShape>(schema: ZodObject<T>): zm._Schema<T> {\n return parseObject(schema);\n}\n\n// Helpers\nfunction parseObject<T extends ZodRawShape>(obj: ZodObject<T>): zm._Schema<T> {\n const object: any = {};\n for (const [key, field] of Object.entries(obj.shape)) {\n if (field instanceof ZodObject) {\n object[key] = parseObject(field);\n } else {\n const f = parseField(field);\n if (!f) throw new Error(`Unsupported field type: ${field.constructor}`);\n\n object[key] = f;\n }\n }\n\n return object;\n}\n\nfunction parseField<T>(\n field: ZodType<T>,\n required = true,\n def?: T,\n refinement?: zm.EffectValidator<T>,\n): zm.mField | null {\n const field_type = field.constructor.name;\n\n if (\"__zm_type\" in field && field.__zm_type === \"ObjectId\") {\n const ref = (<any>field).__zm_ref;\n const unique = (<any>field).__zm_unique;\n return parseObjectId(required, ref, unique);\n }\n\n if (\"__zm_type\" in field && field.__zm_type === \"UUID\") {\n const unique = (<any>field).__zm_unique;\n return parseUUID(required, unique);\n }\n\n if (field instanceof ZodObject) {\n return parseObject(field);\n }\n\n if (field instanceof ZodNumber) {\n const isUnique = field.__zm_unique ?? false;\n return parseNumber(\n field,\n required,\n def as number,\n isUnique,\n refinement as zm.EffectValidator<number>,\n );\n }\n\n if (field instanceof ZodString) {\n const isUnique = field.__zm_unique ?? false;\n return parseString(\n field,\n required,\n def as string,\n isUnique,\n refinement as zm.EffectValidator<string>,\n );\n }\n\n if (field instanceof ZodEnum) {\n return parseEnum(Object.keys(field.Values), required, def as string);\n }\n\n if (field_type === \"ZodBoolean\") {\n return parseBoolean(required, def as boolean);\n }\n\n if (field instanceof ZodDate) {\n const isUnique = field.__zm_unique ?? false;\n return parseDate(\n required,\n def as Date,\n refinement as zm.EffectValidator<Date>,\n isUnique,\n );\n }\n\n if (field instanceof ZodArray) {\n return parseArray(\n required,\n field.element,\n def as T extends Array<infer K> ? K[] : never,\n );\n }\n\n if (field instanceof ZodDefault) {\n return parseField(field._def.innerType, required, field._def.defaultValue());\n }\n\n if (field instanceof ZodOptional) {\n return parseField(field._def.innerType, false, undefined);\n }\n\n if (field instanceof ZodNullable) {\n return parseField(field._def.innerType, false, def || null);\n }\n\n if (field instanceof ZodUnion) {\n return parseField(field._def.options[0]);\n }\n\n if (field_type === \"ZodAny\") {\n return parseMixed(required, def);\n }\n\n if (field instanceof ZodMap || field instanceof ZodRecord) {\n return parseMap(\n required,\n field.keySchema,\n def as Map<\n zm.UnwrapZodType<typeof field.keySchema>,\n zm.UnwrapZodType<typeof field.valueSchema>\n >,\n );\n }\n\n if (field instanceof ZodEffects) {\n const effect = field._def.effect;\n\n if (effect.type === \"refinement\") {\n const validation = (<any>effect).__zm_validation as zm.EffectValidator<T>;\n return parseField(field._def.schema, required, def, validation);\n }\n }\n\n return null;\n}\n\nfunction parseNumber(\n field: ZodNumber,\n required = true,\n def?: number,\n unique = false,\n validate?: zm.EffectValidator<number>,\n): zm.mNumber {\n const output: zm.mNumber = {\n type: Number,\n default: def,\n min: field.minValue ?? undefined,\n max: field.maxValue ?? undefined,\n required,\n unique,\n };\n\n if (validate) output.validate = validate;\n return output;\n}\n\nfunction parseString(\n field: ZodString,\n required = true,\n def?: string,\n unique = false,\n validate?: zm.EffectValidator<string>,\n): zm.mString {\n const output: zm.mString = {\n type: String,\n default: def,\n required,\n minLength: field.minLength ?? undefined,\n maxLength: field.maxLength ?? undefined,\n unique,\n };\n\n if (validate) output.validate = validate;\n return output;\n}\n\nfunction parseEnum(values: string[], required = true, def?: string): zm.mString {\n return {\n type: String,\n unique: false,\n default: def,\n enum: values,\n required,\n };\n}\n\nfunction parseBoolean(required = true, def?: boolean): zm.mBoolean {\n return {\n type: Boolean,\n default: def,\n required,\n };\n}\n\nfunction parseDate(\n required = true,\n def?: Date,\n validate?: zm.EffectValidator<Date>,\n unique = false,\n): zm.mDate {\n const output: zm.mDate = {\n type: Date,\n default: def,\n required,\n unique,\n };\n\n if (validate) output.validate = validate;\n return output;\n}\n\nfunction parseObjectId(required = true, ref?: string, unique = false): zm.mObjectId {\n const output: zm.mObjectId = {\n type: SchemaTypes.ObjectId,\n required,\n unique,\n };\n\n if (ref) output.ref = ref;\n return output;\n}\n\n// biome-ignore lint/style/useDefaultParameterLast: Should be consistent with other functions\nfunction parseArray<T>(required = true, element: ZodType<T>, def?: T[]): zm.mArray<T> {\n const innerType = parseField(element);\n if (!innerType) throw new Error(\"Unsupported array type\");\n return {\n type: [innerType as zm._Field<T>],\n default: def,\n required,\n };\n}\n\nfunction parseMap<T, K>(\n // biome-ignore lint/style/useDefaultParameterLast: Consistency\n required = true,\n key: ZodType<T>,\n def?: Map<NoInfer<T>, K>,\n): zm.mMap<T, K> {\n const pointer = typeConstructor(key);\n return {\n type: Map,\n of: pointer,\n default: def,\n required,\n };\n}\n\nfunction typeConstructor<T>(t: ZodType<T>) {\n switch (true) {\n case t instanceof ZodString:\n return String;\n case t instanceof ZodEnum:\n return String;\n case t instanceof ZodNumber:\n return Number;\n case t instanceof ZodDate:\n return Date;\n default:\n return undefined;\n }\n}\n\nfunction parseUUID(required = true, unique = false): zm.mUUID {\n return {\n type: SchemaTypes.UUID,\n required,\n unique,\n };\n}\n\nfunction parseMixed(required = true, def?: unknown): zm.mMixed<unknown> {\n return {\n type: SchemaTypes.Mixed,\n default: def,\n required,\n };\n}\n\nexport default zodSchema;\n","import { Types, isValidObjectId } from \"mongoose\";\nimport type { zm } from \"mongoose.types\";\nimport { type CustomErrorParams, z } from \"zod\";\n\ndeclare module \"zod\" {\n interface ZodString {\n unique: (arg?: boolean) => ZodString;\n __zm_unique: boolean;\n }\n\n interface ZodNumber {\n unique: (arg?: boolean) => ZodNumber;\n __zm_unique: boolean;\n }\n\n interface ZodDate {\n unique: (arg?: boolean) => ZodDate;\n __zm_unique: boolean;\n }\n\n namespace z {\n function objectId(ref?: string): zm.zID;\n function mongoUUID(): zm.zUUID;\n }\n\n interface ZodType<\n Output = any,\n Def extends z.ZodTypeDef = z.ZodTypeDef,\n Input = Output,\n > {\n // For future use\n }\n}\n\nexport function extendZod(z_0: typeof z) {\n // Prevent zod from being extended multiple times\n if ((<any>z_0).__zm_extended) return;\n (<any>z_0).__zm_extended = true;\n\n const _refine = z_0.ZodType.prototype.refine;\n z_0.ZodType.prototype.refine = function <T>(\n check: (arg0: T) => boolean,\n opts: string | CustomErrorParams | ((arg: T) => CustomErrorParams),\n ) {\n const zEffect = _refine.bind(this)(check, opts);\n\n let message: string | undefined | ((v: T) => string | undefined) = undefined;\n if (typeof opts === \"string\") message = opts;\n else if (\"message\" in opts) message = opts.message;\n\n (<any>zEffect._def.effect).__zm_validation = {\n validator: check,\n message: message,\n };\n\n return zEffect;\n };\n\n z_0.ZodString.prototype.unique = function (arg = true) {\n this.__zm_unique = arg;\n return this;\n };\n\n z_0.ZodNumber.prototype.unique = function (arg = true) {\n this.__zm_unique = arg;\n return this;\n };\n\n z_0.ZodDate.prototype.unique = function (arg = true) {\n this.__zm_unique = arg;\n return this;\n };\n\n (<any>z_0).objectId = (ref?: string) => {\n const output = z\n .string()\n .refine((v) => isValidObjectId(v), { message: \"Invalid ObjectId\" })\n .or(z.instanceof(Types.ObjectId));\n\n (<any>output).__zm_type = \"ObjectId\";\n (<any>output).__zm_ref = ref;\n\n (<any>output).ref = function (ref: string) {\n (<any>this).__zm_ref = ref;\n return this;\n };\n\n (<any>output).unique = function (val = true) {\n (<any>this).__zm_unique = val;\n return this;\n };\n\n return output;\n };\n\n (<any>z_0).mongoUUID = () => {\n const output = z\n .string()\n .uuid({ message: \"Invalid UUID\" })\n .or(z.instanceof(Types.UUID).describe(\"UUID\"));\n (<any>output).__zm_type = \"UUID\";\n\n (<any>output).unique = function (val = true) {\n (<any>this).__zm_unique = val;\n return this;\n };\n\n return output;\n };\n}\n"],"mappings":"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","names":["import_mongoose","import_zod","extendZod","z_0","__zm_extended","_refine","ZodType","prototype","refine","check","opts","zEffect","bind","message","undefined","_def","effect","__zm_validation","validator","ZodString","unique","arg","__zm_unique","ZodNumber","ZodDate","objectId","ref","output","z","string","v","isValidObjectId","or","instanceof","Types","ObjectId","__zm_type","__zm_ref","val","mongoUUID","uuid","UUID","describe","zodSchema","schema","options","definition","parseObject","Schema","zodSchemaRaw","obj","object","key","field","Object","entries","shape","ZodObject","f","parseField","Error","constructor","required","def","refinement","field_type","name","__zm_type","ref","__zm_ref","unique","__zm_unique","parseObjectId","parseUUID","ZodNumber","isUnique","parseNumber","ZodString","parseString","ZodEnum","parseEnum","keys","Values","parseBoolean","ZodDate","parseDate","ZodArray","parseArray","element","ZodDefault","_def","innerType","defaultValue","ZodOptional","undefined","ZodNullable","ZodUnion","parseMixed","ZodMap","ZodRecord","parseMap","keySchema","ZodEffects","effect","type","validation","__zm_validation","validate","output","Number","default","min","minValue","max","maxValue","String","minLength","maxLength","values","enum","Boolean","Date","SchemaTypes","ObjectId","pointer","typeConstructor","Map","of","t","UUID","Mixed"]}
package/dist/index.d.cts CHANGED
@@ -1,12 +1,25 @@
1
- import { Types, SchemaTypes, Schema } from 'mongoose';
2
- import { ZodRawShape, ZodObject, z, ZodUnion, ZodEffects, ZodString, ZodType } from 'zod';
1
+ import { Types, SchemaTypes, SchemaOptions, Schema } from 'mongoose';
2
+ import { z, ZodType, ZodRawShape, ZodObject } from 'zod';
3
3
 
4
4
  declare namespace zm {
5
+ interface zID extends z.ZodUnion<[
6
+ z.ZodString,
7
+ z.ZodType<Types.ObjectId, z.ZodTypeDef, Types.ObjectId>
8
+ ]> {
9
+ __zm_type: "ObjectId";
10
+ __zm_ref?: string;
11
+ ref: (ref: string) => zID;
12
+ unique: (val?: boolean) => zID;
13
+ }
14
+ interface zUUID extends z.ZodUnion<[z.ZodString, z.ZodType<Types.UUID, z.ZodTypeDef, Types.UUID>]> {
15
+ __zm_type: "UUID";
16
+ unique: (val?: boolean) => zID;
17
+ }
5
18
  interface _Field<T> {
6
19
  required: boolean;
7
20
  default?: T;
8
- validation?: {
9
- validate: (v: T) => boolean;
21
+ validate?: {
22
+ validator: (v: T) => boolean;
10
23
  message?: string;
11
24
  };
12
25
  }
@@ -29,28 +42,63 @@ declare namespace zm {
29
42
  }
30
43
  interface mDate extends _Field<Date> {
31
44
  type: DateConstructor;
45
+ unique: boolean;
32
46
  }
33
47
  interface mObjectId extends _Field<Types.ObjectId> {
34
48
  type: typeof SchemaTypes.ObjectId;
49
+ unique?: boolean;
35
50
  ref?: string;
36
51
  }
37
52
  interface mUUID extends _Field<Types.UUID> {
38
53
  type: typeof SchemaTypes.UUID;
54
+ unique?: boolean;
39
55
  ref?: string;
40
56
  }
41
- type mArray<K> = [_Field<K[]>];
57
+ interface mArray<K> extends _Field<K[]> {
58
+ type: [_Field<K>];
59
+ }
42
60
  interface mMixed<T> extends _Field<T> {
43
61
  type: typeof SchemaTypes.Mixed;
44
62
  }
45
- type mField = mString | mNumber | mBoolean | mDate | mObjectId | mUUID | mMixed<unknown> | mArray<unknown> | _Schema<unknown>;
63
+ type Constructor = StringConstructor | NumberConstructor | ObjectConstructor | DateConstructor | BooleanConstructor | BigIntConstructor;
64
+ interface mMap<T, K> extends _Field<Map<T, K>> {
65
+ type: typeof Map;
66
+ of?: Constructor;
67
+ }
68
+ type mField = mString | mNumber | mBoolean | mDate | mObjectId | mUUID | mMixed<unknown> | mArray<unknown> | _Schema<unknown> | mMap<unknown, unknown>;
46
69
  type _Schema<T> = {
47
70
  [K in keyof T]: _Field<T[K]> | _Schema<T[K]>;
48
71
  };
72
+ type UnwrapZodType<T> = T extends ZodType<infer K> ? K : never;
73
+ type EffectValidator<T> = {
74
+ validator: (v: T) => boolean;
75
+ message?: string;
76
+ };
77
+ }
78
+
79
+ declare module "zod" {
80
+ interface ZodString {
81
+ unique: (arg?: boolean) => ZodString;
82
+ __zm_unique: boolean;
83
+ }
84
+ interface ZodNumber {
85
+ unique: (arg?: boolean) => ZodNumber;
86
+ __zm_unique: boolean;
87
+ }
88
+ interface ZodDate {
89
+ unique: (arg?: boolean) => ZodDate;
90
+ __zm_unique: boolean;
91
+ }
92
+ namespace z {
93
+ function objectId(ref?: string): zm.zID;
94
+ function mongoUUID(): zm.zUUID;
95
+ }
96
+ interface ZodType<Output = any, Def extends z.ZodTypeDef = z.ZodTypeDef, Input = Output> {
97
+ }
49
98
  }
99
+ declare function extendZod(z_0: typeof z): void;
50
100
 
51
- declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>): Schema<z.infer<typeof schema>>;
101
+ declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>, options?: SchemaOptions<any>): Schema<z.infer<typeof schema>>;
52
102
  declare function zodSchemaRaw<T extends ZodRawShape>(schema: ZodObject<T>): zm._Schema<T>;
53
- declare const zId: ZodUnion<[ZodEffects<ZodString, string, string>, ZodType<Types.ObjectId, z.ZodTypeDef, Types.ObjectId>]>;
54
- declare const zUUID: ZodUnion<[ZodString, ZodType<Types.UUID, z.ZodTypeDef, Types.UUID>]>;
55
103
 
56
- export { zodSchema as default, zId, zUUID, zodSchema, zodSchemaRaw };
104
+ export { zodSchema as default, extendZod, zodSchema, zodSchemaRaw };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,25 @@
1
- import { Types, SchemaTypes, Schema } from 'mongoose';
2
- import { ZodRawShape, ZodObject, z, ZodUnion, ZodEffects, ZodString, ZodType } from 'zod';
1
+ import { Types, SchemaTypes, SchemaOptions, Schema } from 'mongoose';
2
+ import { z, ZodType, ZodRawShape, ZodObject } from 'zod';
3
3
 
4
4
  declare namespace zm {
5
+ interface zID extends z.ZodUnion<[
6
+ z.ZodString,
7
+ z.ZodType<Types.ObjectId, z.ZodTypeDef, Types.ObjectId>
8
+ ]> {
9
+ __zm_type: "ObjectId";
10
+ __zm_ref?: string;
11
+ ref: (ref: string) => zID;
12
+ unique: (val?: boolean) => zID;
13
+ }
14
+ interface zUUID extends z.ZodUnion<[z.ZodString, z.ZodType<Types.UUID, z.ZodTypeDef, Types.UUID>]> {
15
+ __zm_type: "UUID";
16
+ unique: (val?: boolean) => zID;
17
+ }
5
18
  interface _Field<T> {
6
19
  required: boolean;
7
20
  default?: T;
8
- validation?: {
9
- validate: (v: T) => boolean;
21
+ validate?: {
22
+ validator: (v: T) => boolean;
10
23
  message?: string;
11
24
  };
12
25
  }
@@ -29,28 +42,63 @@ declare namespace zm {
29
42
  }
30
43
  interface mDate extends _Field<Date> {
31
44
  type: DateConstructor;
45
+ unique: boolean;
32
46
  }
33
47
  interface mObjectId extends _Field<Types.ObjectId> {
34
48
  type: typeof SchemaTypes.ObjectId;
49
+ unique?: boolean;
35
50
  ref?: string;
36
51
  }
37
52
  interface mUUID extends _Field<Types.UUID> {
38
53
  type: typeof SchemaTypes.UUID;
54
+ unique?: boolean;
39
55
  ref?: string;
40
56
  }
41
- type mArray<K> = [_Field<K[]>];
57
+ interface mArray<K> extends _Field<K[]> {
58
+ type: [_Field<K>];
59
+ }
42
60
  interface mMixed<T> extends _Field<T> {
43
61
  type: typeof SchemaTypes.Mixed;
44
62
  }
45
- type mField = mString | mNumber | mBoolean | mDate | mObjectId | mUUID | mMixed<unknown> | mArray<unknown> | _Schema<unknown>;
63
+ type Constructor = StringConstructor | NumberConstructor | ObjectConstructor | DateConstructor | BooleanConstructor | BigIntConstructor;
64
+ interface mMap<T, K> extends _Field<Map<T, K>> {
65
+ type: typeof Map;
66
+ of?: Constructor;
67
+ }
68
+ type mField = mString | mNumber | mBoolean | mDate | mObjectId | mUUID | mMixed<unknown> | mArray<unknown> | _Schema<unknown> | mMap<unknown, unknown>;
46
69
  type _Schema<T> = {
47
70
  [K in keyof T]: _Field<T[K]> | _Schema<T[K]>;
48
71
  };
72
+ type UnwrapZodType<T> = T extends ZodType<infer K> ? K : never;
73
+ type EffectValidator<T> = {
74
+ validator: (v: T) => boolean;
75
+ message?: string;
76
+ };
77
+ }
78
+
79
+ declare module "zod" {
80
+ interface ZodString {
81
+ unique: (arg?: boolean) => ZodString;
82
+ __zm_unique: boolean;
83
+ }
84
+ interface ZodNumber {
85
+ unique: (arg?: boolean) => ZodNumber;
86
+ __zm_unique: boolean;
87
+ }
88
+ interface ZodDate {
89
+ unique: (arg?: boolean) => ZodDate;
90
+ __zm_unique: boolean;
91
+ }
92
+ namespace z {
93
+ function objectId(ref?: string): zm.zID;
94
+ function mongoUUID(): zm.zUUID;
95
+ }
96
+ interface ZodType<Output = any, Def extends z.ZodTypeDef = z.ZodTypeDef, Input = Output> {
97
+ }
49
98
  }
99
+ declare function extendZod(z_0: typeof z): void;
50
100
 
51
- declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>): Schema<z.infer<typeof schema>>;
101
+ declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>, options?: SchemaOptions<any>): Schema<z.infer<typeof schema>>;
52
102
  declare function zodSchemaRaw<T extends ZodRawShape>(schema: ZodObject<T>): zm._Schema<T>;
53
- declare const zId: ZodUnion<[ZodEffects<ZodString, string, string>, ZodType<Types.ObjectId, z.ZodTypeDef, Types.ObjectId>]>;
54
- declare const zUUID: ZodUnion<[ZodString, ZodType<Types.UUID, z.ZodTypeDef, Types.UUID>]>;
55
103
 
56
- export { zodSchema as default, zId, zUUID, zodSchema, zodSchemaRaw };
104
+ export { zodSchema as default, extendZod, zodSchema, zodSchemaRaw };
package/dist/index.js CHANGED
@@ -1,30 +1,80 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
1
4
  // src/index.ts
2
- import { Schema, SchemaTypes, Types, isValidObjectId } from "mongoose";
3
- import {
4
- ZodAny,
5
- ZodArray,
6
- ZodBoolean,
7
- ZodDate,
8
- ZodDefault,
9
- ZodEffects,
10
- ZodEnum,
11
- ZodNullable,
12
- ZodNumber,
13
- ZodObject,
14
- ZodOptional,
15
- ZodString,
16
- ZodUnion,
17
- z
18
- } from "zod";
19
- function zodSchema(schema) {
5
+ import { Schema, SchemaTypes } from "mongoose";
6
+ import { ZodArray, ZodDate, ZodDefault, ZodEffects, ZodEnum, ZodMap, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodRecord, ZodString, ZodUnion } from "zod";
7
+
8
+ // src/extension.ts
9
+ import { Types, isValidObjectId } from "mongoose";
10
+ import { z } from "zod";
11
+ function extendZod(z_0) {
12
+ if (z_0.__zm_extended) return;
13
+ z_0.__zm_extended = true;
14
+ const _refine = z_0.ZodType.prototype.refine;
15
+ z_0.ZodType.prototype.refine = function(check, opts) {
16
+ const zEffect = _refine.bind(this)(check, opts);
17
+ let message = void 0;
18
+ if (typeof opts === "string") message = opts;
19
+ else if ("message" in opts) message = opts.message;
20
+ zEffect._def.effect.__zm_validation = {
21
+ validator: check,
22
+ message
23
+ };
24
+ return zEffect;
25
+ };
26
+ z_0.ZodString.prototype.unique = function(arg = true) {
27
+ this.__zm_unique = arg;
28
+ return this;
29
+ };
30
+ z_0.ZodNumber.prototype.unique = function(arg = true) {
31
+ this.__zm_unique = arg;
32
+ return this;
33
+ };
34
+ z_0.ZodDate.prototype.unique = function(arg = true) {
35
+ this.__zm_unique = arg;
36
+ return this;
37
+ };
38
+ z_0.objectId = (ref) => {
39
+ const output = z.string().refine((v) => isValidObjectId(v), {
40
+ message: "Invalid ObjectId"
41
+ }).or(z.instanceof(Types.ObjectId));
42
+ output.__zm_type = "ObjectId";
43
+ output.__zm_ref = ref;
44
+ output.ref = function(ref2) {
45
+ this.__zm_ref = ref2;
46
+ return this;
47
+ };
48
+ output.unique = function(val = true) {
49
+ this.__zm_unique = val;
50
+ return this;
51
+ };
52
+ return output;
53
+ };
54
+ z_0.mongoUUID = () => {
55
+ const output = z.string().uuid({
56
+ message: "Invalid UUID"
57
+ }).or(z.instanceof(Types.UUID).describe("UUID"));
58
+ output.__zm_type = "UUID";
59
+ output.unique = function(val = true) {
60
+ this.__zm_unique = val;
61
+ return this;
62
+ };
63
+ return output;
64
+ };
65
+ }
66
+ __name(extendZod, "extendZod");
67
+
68
+ // src/index.ts
69
+ function zodSchema(schema, options) {
20
70
  const definition = parseObject(schema);
21
- return new Schema(definition);
71
+ return new Schema(definition, options);
22
72
  }
73
+ __name(zodSchema, "zodSchema");
23
74
  function zodSchemaRaw(schema) {
24
75
  return parseObject(schema);
25
76
  }
26
- var zId = z.string().refine((v) => isValidObjectId(v), { message: "Invalid ObjectId" }).or(z.instanceof(Types.ObjectId).describe("ObjectId"));
27
- var zUUID = z.string().uuid({ message: "Invalid UUID" }).or(z.instanceof(Types.UUID).describe("UUID"));
77
+ __name(zodSchemaRaw, "zodSchemaRaw");
28
78
  function parseObject(obj) {
29
79
  const object = {};
30
80
  for (const [key, field] of Object.entries(obj.shape)) {
@@ -32,56 +82,50 @@ function parseObject(obj) {
32
82
  object[key] = parseObject(field);
33
83
  } else {
34
84
  const f = parseField(field);
35
- if (f)
36
- object[key] = f;
37
- else
38
- console.error(
39
- `Key ${key}: Unsupported field type: ${field.constructor}`
40
- );
85
+ if (!f) throw new Error(`Unsupported field type: ${field.constructor}`);
86
+ object[key] = f;
41
87
  }
42
88
  }
43
89
  return object;
44
90
  }
45
- function parseField(field, required, def) {
91
+ __name(parseObject, "parseObject");
92
+ function parseField(field, required = true, def, refinement) {
93
+ const field_type = field.constructor.name;
94
+ if ("__zm_type" in field && field.__zm_type === "ObjectId") {
95
+ const ref = field.__zm_ref;
96
+ const unique = field.__zm_unique;
97
+ return parseObjectId(required, ref, unique);
98
+ }
99
+ if ("__zm_type" in field && field.__zm_type === "UUID") {
100
+ const unique = field.__zm_unique;
101
+ return parseUUID(required, unique);
102
+ }
46
103
  if (field instanceof ZodObject) {
47
104
  return parseObject(field);
48
105
  }
49
106
  if (field instanceof ZodNumber) {
50
- return parseNumber(
51
- field,
52
- required,
53
- def,
54
- field.description?.toLocaleLowerCase() === "unique"
55
- // validate as (v: number) => boolean,
56
- );
107
+ const isUnique = field.__zm_unique ?? false;
108
+ return parseNumber(field, required, def, isUnique, refinement);
57
109
  }
58
110
  if (field instanceof ZodString) {
59
- return parseString(
60
- field,
61
- required,
62
- def,
63
- field.description?.toLocaleLowerCase() === "unique"
64
- // validate as (v: string) => boolean,
65
- );
111
+ const isUnique = field.__zm_unique ?? false;
112
+ return parseString(field, required, def, isUnique, refinement);
66
113
  }
67
114
  if (field instanceof ZodEnum) {
68
115
  return parseEnum(Object.keys(field.Values), required, def);
69
116
  }
70
- if (field instanceof ZodBoolean) {
117
+ if (field_type === "ZodBoolean") {
71
118
  return parseBoolean(required, def);
72
119
  }
73
120
  if (field instanceof ZodDate) {
74
- return parseDate(required, def);
121
+ const isUnique = field.__zm_unique ?? false;
122
+ return parseDate(required, def, refinement, isUnique);
75
123
  }
76
124
  if (field instanceof ZodArray) {
77
- return [parseField(field.element)];
125
+ return parseArray(required, field.element, def);
78
126
  }
79
127
  if (field instanceof ZodDefault) {
80
- return parseField(
81
- field._def.innerType,
82
- required,
83
- field._def.defaultValue()
84
- );
128
+ return parseField(field._def.innerType, required, field._def.defaultValue());
85
129
  }
86
130
  if (field instanceof ZodOptional) {
87
131
  return parseField(field._def.innerType, false, void 0);
@@ -89,51 +133,27 @@ function parseField(field, required, def) {
89
133
  if (field instanceof ZodNullable) {
90
134
  return parseField(field._def.innerType, false, def || null);
91
135
  }
92
- if (field.description?.startsWith("ObjectId")) {
93
- const ref = field.description.split(":")[1];
94
- if (ref)
95
- return parseObjectIdRef(required, ref);
96
- return parseObjectId(required);
97
- }
98
- if (field.description?.startsWith("UUID")) {
99
- const ref = field.description.split(":")[1];
100
- if (ref)
101
- return parseUUIDRef(required, ref);
102
- return parseUUID(required);
103
- }
104
136
  if (field instanceof ZodUnion) {
105
137
  return parseField(field._def.options[0]);
106
138
  }
107
- if (field instanceof ZodAny) {
139
+ if (field_type === "ZodAny") {
108
140
  return parseMixed(required, def);
109
141
  }
142
+ if (field instanceof ZodMap || field instanceof ZodRecord) {
143
+ return parseMap(required, field.keySchema, def);
144
+ }
110
145
  if (field instanceof ZodEffects) {
111
- if (field._def.effect.type === "refinement") {
112
- return parseField(
113
- field._def.schema,
114
- required,
115
- def
116
- // field._def.effect.refinement as (v: T) => boolean,
117
- );
146
+ const effect = field._def.effect;
147
+ if (effect.type === "refinement") {
148
+ const validation = effect.__zm_validation;
149
+ return parseField(field._def.schema, required, def, validation);
118
150
  }
119
151
  }
120
152
  return null;
121
153
  }
154
+ __name(parseField, "parseField");
122
155
  function parseNumber(field, required = true, def, unique = false, validate) {
123
- if (validate) {
124
- return {
125
- type: Number,
126
- default: def,
127
- min: field.minValue ?? void 0,
128
- max: field.maxValue ?? void 0,
129
- validation: {
130
- validate
131
- },
132
- required,
133
- unique
134
- };
135
- }
136
- return {
156
+ const output = {
137
157
  type: Number,
138
158
  default: def,
139
159
  min: field.minValue ?? void 0,
@@ -141,40 +161,33 @@ function parseNumber(field, required = true, def, unique = false, validate) {
141
161
  required,
142
162
  unique
143
163
  };
164
+ if (validate) output.validate = validate;
165
+ return output;
144
166
  }
167
+ __name(parseNumber, "parseNumber");
145
168
  function parseString(field, required = true, def, unique = false, validate) {
146
- if (validate) {
147
- return {
148
- type: String,
149
- default: def,
150
- required,
151
- minLength: field.minLength ?? void 0,
152
- maxLength: field.maxLength ?? void 0,
153
- validation: {
154
- validate
155
- },
156
- unique
157
- };
158
- }
159
- return {
169
+ const output = {
160
170
  type: String,
161
171
  default: def,
162
- // TODO: match: field.regex(),
163
172
  required,
164
173
  minLength: field.minLength ?? void 0,
165
174
  maxLength: field.maxLength ?? void 0,
166
175
  unique
167
176
  };
177
+ if (validate) output.validate = validate;
178
+ return output;
168
179
  }
180
+ __name(parseString, "parseString");
169
181
  function parseEnum(values, required = true, def) {
170
182
  return {
171
183
  type: String,
184
+ unique: false,
172
185
  default: def,
173
186
  enum: values,
174
- required,
175
- unique: false
187
+ required
176
188
  };
177
189
  }
190
+ __name(parseEnum, "parseEnum");
178
191
  function parseBoolean(required = true, def) {
179
192
  return {
180
193
  type: Boolean,
@@ -182,39 +195,73 @@ function parseBoolean(required = true, def) {
182
195
  required
183
196
  };
184
197
  }
185
- function parseDate(required = true, def) {
186
- return {
198
+ __name(parseBoolean, "parseBoolean");
199
+ function parseDate(required = true, def, validate, unique = false) {
200
+ const output = {
187
201
  type: Date,
188
202
  default: def,
189
- required
203
+ required,
204
+ unique
190
205
  };
206
+ if (validate) output.validate = validate;
207
+ return output;
191
208
  }
192
- function parseObjectId(required = true) {
193
- return {
209
+ __name(parseDate, "parseDate");
210
+ function parseObjectId(required = true, ref, unique = false) {
211
+ const output = {
194
212
  type: SchemaTypes.ObjectId,
195
- required
213
+ required,
214
+ unique
196
215
  };
216
+ if (ref) output.ref = ref;
217
+ return output;
197
218
  }
198
- function parseObjectIdRef(required = true, ref) {
219
+ __name(parseObjectId, "parseObjectId");
220
+ function parseArray(required = true, element, def) {
221
+ const innerType = parseField(element);
222
+ if (!innerType) throw new Error("Unsupported array type");
199
223
  return {
200
- type: SchemaTypes.ObjectId,
201
- ref,
224
+ type: [
225
+ innerType
226
+ ],
227
+ default: def,
202
228
  required
203
229
  };
204
230
  }
205
- function parseUUID(required = true) {
231
+ __name(parseArray, "parseArray");
232
+ function parseMap(required = true, key, def) {
233
+ const pointer = typeConstructor(key);
206
234
  return {
207
- type: SchemaTypes.UUID,
235
+ type: Map,
236
+ of: pointer,
237
+ default: def,
208
238
  required
209
239
  };
210
240
  }
211
- function parseUUIDRef(required = true, ref) {
241
+ __name(parseMap, "parseMap");
242
+ function typeConstructor(t) {
243
+ switch (true) {
244
+ case t instanceof ZodString:
245
+ return String;
246
+ case t instanceof ZodEnum:
247
+ return String;
248
+ case t instanceof ZodNumber:
249
+ return Number;
250
+ case t instanceof ZodDate:
251
+ return Date;
252
+ default:
253
+ return void 0;
254
+ }
255
+ }
256
+ __name(typeConstructor, "typeConstructor");
257
+ function parseUUID(required = true, unique = false) {
212
258
  return {
213
259
  type: SchemaTypes.UUID,
214
- ref,
215
- required
260
+ required,
261
+ unique
216
262
  };
217
263
  }
264
+ __name(parseUUID, "parseUUID");
218
265
  function parseMixed(required = true, def) {
219
266
  return {
220
267
  type: SchemaTypes.Mixed,
@@ -222,11 +269,11 @@ function parseMixed(required = true, def) {
222
269
  required
223
270
  };
224
271
  }
272
+ __name(parseMixed, "parseMixed");
225
273
  var src_default = zodSchema;
226
274
  export {
227
275
  src_default as default,
228
- zId,
229
- zUUID,
276
+ extendZod,
230
277
  zodSchema,
231
278
  zodSchemaRaw
232
279
  };