UNPKG

@videsk/mongoose-dummy

Version:

Random data generator based on mongoose schema, with very flexible options, populate feature and easily integrable with random data generators libraries.

12 lines (11 loc) 4.17 kB
/** * Copyright (C) 2026 by Videsk - All Rights Reserved * @name @videsk/mongoose-dummy * @author Videsk * @license UNLICENSED * Written by Videsk <devs@videsk.io> * * Random data generator based on mongoose schema, with very flexible options, populate feature and easily integrable with random data generators libraries. * */ "use strict";var e=require("mongoose"),t=require("node:crypto");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a=n(e);const{Schema:r,Types:s}=a.default;class o{constructor(e){if(!e)throw new Error("Pass a valid mongoose instance.");this.mongooseInstance=e,this.schemas=e.models,this.config={generators:{},maxPopulateDepth:1,defaultFilter:()=>!0}}setup(e={}){return this.config=Object.assign(this.config,e),this}set maxPopulateDepth(e){this.config.maxPopulateDepth=e}get maxPopulateDepth(){return this.config.maxPopulateDepth}set defaultFilter(e){this.config.defaultFilter=e}get defaultFilter(){return this.config.defaultFilter}set generators(e){this.config.generators=Object.assign(this.config.generators,e)}get generators(){return this.config.generators}generate(e,t){const n=t&&"string"==typeof t?this.getModel(t):this.baseModel;return this.iterate(n,{},0,e||this.config.defaultFilter)}model(e=""){return this.baseModel=this.getModel(e),this}getModel(e){if(!(e in this.schemas))throw new Error(`The model name "${e}" is not present in schema models. Is case sensitive!`);return this.schemas[e].schema}get objectModel(){if(!this.baseModel)throw new Error("Set the model before try get the object with model() method.");return this.baseModel.obj}iterate(e,t={},n=0,a=(()=>!0)){const{paths:r}=e;for(const e of Object.values(r))if(o.canParse(e,this.config.dummyKey)&&o.query(e,a)){const r=e.path.split("."),s=r.pop();r.reduce(((e,t)=>e[t]=e[t]||{}),t)[s]=this.evaluateDummy(e,n,t,a)}return t}evaluateDummy(e,t=0,n={},a=(()=>!0)){const{arrayLength:i=3,dummyKey:c="dummy",maxPopulateDepth:u}=this.config||{},{instance:h}=e;if(t>u)return o.getFallbackValue(e);const{length:m=i}=e.options[c]||{};if(e.options[c]instanceof Function)try{return e.options[c].call(n,this.generators)}catch{return o.getFallbackValue(e)}else{if(e instanceof r.Types.ObjectId||"ObjectId"===h)return this.evaluateObjectId(e,t,a);if(e instanceof r.Types.DocumentArray||e instanceof r.Types.Array||"Array"===h)return[...Array(m)].map((()=>this.getArrayItem(e,n,t,a)));if(e instanceof s.Subdocument||e.schema?.paths||"Embedded"===h)return this.iterate(e.schema,{},t)}return o.getFallbackValue(e)}getArrayItem(e,t,n=0,a=(()=>!0)){if(e?.schema instanceof r)return this.iterate(e.schema,{},n+1,a);const s=e.caster??e.embeddedSchemaType;return s instanceof r.Types.ObjectId?this.evaluateObjectId(s,n,a):this.evaluateDummy(s,n+1,t,a)}evaluateObjectId(e,t=0,n=(()=>!0)){const{ref:a,populate:r}=e.options,{maxPopulateDepth:i}=this.config;return a&&r&&t<i?this.iterate(this.getModel(a),{},t+1,n):o.canParse(e)?new s.ObjectId:void 0}static getFallbackValue(e){const{Mixed:n,ObjectId:a,Number:o,Boolean:i,String:c,Map:u,Buffer:h,BigInt:m=o,DocumentArray:l,Decimal128:d}=r.Types,{max:f,min:g,default:p}=e.options,{instance:y}=e;return void 0!==p?p:e instanceof r.Types.Array||e instanceof l||"Array"===y?new s.Array:e instanceof s.Subdocument||e instanceof n||e instanceof u||"Embedded"===y?{}:e instanceof a||"ObjectId"===y?new s.ObjectId:e instanceof o||e instanceof m||e instanceof d||"Number"===y?this.randomNumber(g,f):e instanceof i||"Boolean"===y?Math.random()<.5:e instanceof c||e instanceof h||"String"===y?this.generateStringBasedOnSchemaOptions(e.options):e instanceof r.Types.Date||"Date"===y?new Date:e instanceof(r.Types.UUID||c)?t.randomUUID():null}static randomNumber(e=0,t=99){return Math.floor(Math.random()*t)+e}static generateStringBasedOnSchemaOptions(e={}){const{enum:t,maxLength:n=99,minLength:a=3}=e;return Array.isArray(t)&&t.length>0?t[this.randomNumber(0,t.length-1)]:[...Array(Math.floor(Math.random()*(n-a+1))+a)].map((()=>Math.random().toString(36)[2])).join("")}static canParse(e,t="dummy"){return[t,"populate"].some((t=>e.options.hasOwnProperty(t)))}static query(e,t=(()=>!0)){return t(e.options)}}module.exports=o;