UNPKG

stormflow

Version:

StormFlow is a versatile Node.js data management library designed for efficient data management.

5 lines (4 loc) 14.4 kB
var mt=Object.create;var V=Object.defineProperty;var gt=Object.getOwnPropertyDescriptor;var ht=Object.getOwnPropertyNames;var bt=Object.getPrototypeOf,$t=Object.prototype.hasOwnProperty;var F=(t,n)=>{for(var r in n)V(t,r,{get:n[r],enumerable:!0})},nt=(t,n,r,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of ht(n))!$t.call(t,s)&&s!==r&&V(t,s,{get:()=>n[s],enumerable:!(e=gt(n,s))||e.enumerable});return t};var Mt=(t,n,r)=>(r=t!=null?mt(bt(t)):{},nt(n||!t||!t.__esModule?V(r,"default",{value:t,enumerable:!0}):r,t)),It=t=>nt(V({},"__esModule",{value:!0}),t);var Vt={};F(Vt,{default:()=>qt});module.exports=It(Vt);var St={},h=St;var z={};F(z,{objClone:()=>g,objPathResolve:()=>M,objPathSet:()=>I,objTraverse:()=>D});var g=t=>{if(typeof t!="object"||t===null)return t;if(Array.isArray(t)){let n=new Array(t.length);for(let r=0;r<t.length;r++)n[r]=g(t[r]);return n}else{let n={},r=Object.keys(t);for(let e=0;e<r.length;e++)n[r[e]]=g(t[r[e]]);return n}},D=(t,n)=>rt(t,"",n),rt=(t,n,r)=>{if(typeof t!="object"||t===null)return;let e=Object.keys(t),s=!n;for(let f=0,i=e.length;f<i;f++){let l=e[f],d=t[l],m=s?l:n+"."+l,v=s?null:n,$=d&&typeof d=="object";r({key:l,value:d,parent:t,path:m,parentPath:v,isNode:$}),$&&rt(d,m,r)}},M=(t,n)=>{if(!n)return t;t=t||{};let r=n.split("."),e=t;for(let s=0;s<r.length;s++){if(e==null)return;e=e[r[s]]}return e},I=(t,n,r)=>{let e=n.split("."),s=t;for(let f=0;f<e.length;f++){let i=e[f],d=i===`${+i}`?+i:i;if(["__proto__","constructor"].includes(String(d)))return;if(f===e.length-1)r===void 0?Array.isArray(s)?s.splice(Number(d),1):delete s[d]:s[d]=r;else{let v=e[f+1],$=v===`${+v}`;(!(d in s)||s[d]===null)&&(s[d]=$?[]:{}),s=s[d]}}};var G={};F(G,{getType:()=>c});var c=t=>t==null?t===null?"null":"undefined":Array.isArray(t)?"array":t instanceof Date?"date":typeof t;var _={storage:null,backup:null,backupIntervalId:null},ot=async({storageAdapter:t,backupAdapter:n})=>{if(t&&(_.storage=t),n&&(_.backup=n),await R.initCollections(),n?.init){let r=await n.init();if(r?.backupInterval){let e=r.backupInterval*60*1e3;_.backupIntervalId=setInterval(()=>{_.backup.backup(st())},e)}}},st=()=>{let t={};for(let n in h)t[n]=Array.from(h[n].values()).map(g);return t},X=async(t,n,r)=>{if(!_.storage||!h[n])return;await new Promise(s=>setTimeout(s,0));let e=Array.from(h[n].values()).map(g);await _.storage[t]({collectionName:n,collectionData:e,changes:r})},R={onInsert:async(t,n=[])=>X("insert",t,n),onUpdate:async(t,n=[])=>X("update",t,n),onDelete:async(t,n=[])=>X("delete",t,n),initCollections:async()=>{if(!_.storage)return;let t=await _.storage.init();if(c(t?.collections)==="array")for(let{collectionName:n,collectionData:r}of t.collections)h[n]=new Map(r.map(e=>[e._id,e]))},onBackup:async()=>{_.backup&&await _.backup.backup(st())},stopBackup:()=>{_.backupIntervalId&&(clearInterval(_.backupIntervalId),_.backupIntervalId=null)}};var jt=(t={})=>{if(c(t)!=="object")throw new Error("defaultConfig must be an object");let n=g(t),r=g(t),e=s=>{let f=Object.keys(n);if(c(s)!=="object")throw new Error('Invalid type of options. Expected type is "object"');Object.keys(s).forEach(i=>{if(!f.includes(i)){let m=f.join('", "');throw new Error(`Invalid "${i}" key in options.\r Allowed keys: "${m}"`)}let l=c(n[i]);if(c(s[i])!==l)throw new Error(`Invalid type of "${i}" key in options. Expected type is ${l}`)})};return{getDefaultConfig(){return g(n)},resetConfig(){r=g(n)},getConfig(){return g(r)},setConfig(s){e(s),Object.assign(r,n,s)},get(s){return r[s]},set(s,f){r[s]=f}}},it=jt;var _t=it({strict:!0,defaultFields:!0,verbose:!1}),E=_t;var N={};F(N,{uniqueId:()=>U});var at=Mt(require("crypto"),1),U=()=>at.default.randomBytes(6).toString("hex");var et={};F(et,{timeFromStr:()=>tt,timeNow:()=>J,timeToDateObj:()=>Et,timeToDateStr:()=>At});var J=()=>Math.floor(new Date().getTime()/1e3),tt=t=>Math.floor(new Date(t).getTime()/1e3),Et=t=>new Date(t*1e3),xt=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],vt=["January","February","March","April","May","June","July","August","September","October","November","December"],Dt=["Su","Mo","Tu","We","Th","Fr","Sa"],Tt=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Ct=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],At=(t,n="YYYY-MM-DD HH:mm:ss")=>{let r=(T,k=2)=>String(T).padStart(k,"0"),e=new Date(t*1e3),s=e.getTimezoneOffset(),f=s>0?"-":"+",i=Math.abs(s),l=r(Math.floor(i/60)),d=r(i%60),m=`${f}${l}:${d}`,v=`${f}${l}${d}`,$={YYYY:e.getFullYear(),YY:String(e.getFullYear()).slice(-2),M:e.getMonth()+1,MM:r(e.getMonth()+1),MMM:xt[e.getMonth()],MMMM:vt[e.getMonth()],D:e.getDate(),DD:r(e.getDate()),d:e.getDay(),dd:Dt[e.getDay()],ddd:Tt[e.getDay()],dddd:Ct[e.getDay()],H:e.getHours(),HH:r(e.getHours()),h:e.getHours()%12||12,hh:r(e.getHours()%12||12),m:e.getMinutes(),mm:r(e.getMinutes()),s:e.getSeconds(),ss:r(e.getSeconds()),SSS:r(e.getMilliseconds(),3),A:e.getHours()<12?"AM":"PM",a:e.getHours()<12?"am":"pm"};return n.replace(/ZZ/g,v).replace(/Z/g,m).replace(/YYYY|YY|MMMM|MMM|MM|M|DD|D|dddd|ddd|dd|d|HH|H|hh|h|mm|m|ss|s|SSS|A|a/g,T=>$[T]??T)};var ft=new Map,Ot=["pre","post"],kt=["create","read","update","replace","delete"],Yt=t=>Ot.includes(t),Pt=t=>t==="*"||kt.includes(t),Z=(t,n,r,e)=>{if(c(r)==="array")return r.map(f=>Z(t,n,f,e));if(!Yt(t))throw new Error(`Invalid middleware type: ${t}`);if(c(n)!=="string"||n==="*")throw new Error(`Invalid middleware collection: ${n}`);if(!Pt(r))throw new Error(`Invalid middleware method: ${r}`);if(c(e)!=="function")throw new Error(`Invalid middleware function: ${e}`);let s=U();return ft.set(s,{type:t,collection:n,method:r,fn:e}),s};var Ht=async(t,n,r,e)=>{let s=[];for(let f of ft.values())f.type===t&&f.collection===n&&(f.method==="*"||f.method===r)&&s.push(f);for(let f of s)await f.fn(e)},O=async(t,n,r,e)=>{let s=c(e)==="array"?e:[e];await Promise.all(s.map(f=>Ht(t,n,r,f)))};var Ft=(t,n)=>n.includes(".")?M(t,n):t[n],Y=(t,n)=>{let r=t instanceof Map?Array.from(t.values()):t;if(c(n)!=="object")return r;let e=Object.keys(n);if(e.length===1&&n._id!==void 0)return[t.get(n._id)];if(c(n.$and)==="array")return r.filter(s=>n.$and.every(f=>Y([s],f).length));if(c(n.$or)==="array"){let s=new Set;for(let f of n.$or)for(let i of Y(r,f))s.add(i);return Array.from(s)}if(c(n.$not)==="object"){let s=new Set(Y(r,n.$not));return r.filter(f=>!s.has(f))}if(c(n.$nor)==="array"){let s=new Set;for(let f of n.$nor)for(let i of Y(r,f))s.add(i);return r.filter(f=>!s.has(f))}return r.filter(s=>e.every(f=>{let i=n[f],l=Ft(s,f);if(["object","array"].includes(c(i))){if(i.$eq!==void 0)return l===i.$eq;if(i.$ne!==void 0)return l!==i.$ne;if(i.$in!==void 0)return i.$in.includes(l);if(i.$nin!==void 0)return!i.$nin.includes(l);if(i.$lt!==void 0)return l<i.$lt;if(i.$lte!==void 0)return l<=i.$lte;if(i.$gt!==void 0)return l>i.$gt;if(i.$gte!==void 0)return l>=i.$gte;if(i.$regex!==void 0)return new RegExp(i.$regex,i?.$options).test(l)}else return l===i}))};var x=t=>{if(["object","array"].includes(c(t))){let n=g(t);return D(n,({key:r,value:e,parent:s,path:f})=>{if(c(e)==="object"&&e._ref){let{collection:i,id:l}=e._ref,d=h[i];if(delete s[r],d){let m=d.get(l);if(m){let{_ref:v,...$}=x(m);I(n,f,$)}}}}),n}else return t};var ct=["string","number","boolean","date"],dt=["type","required","default","unique","$ref"],ut=(t={})=>{if(c(t)!=="object"||Object.keys(t).length===0){let r='Invalid "object" type of schema definition.';throw new Error(r)}let n=g(t);return D(n,({key:r,value:e,parent:s,isNode:f})=>{let i=c(e),l=!f&&!s.hasOwnProperty("type");if(i==="function"){let d=e.name.toLowerCase();l&&(s[r]={type:d}),r==="type"&&(s[r]=d)}}),D(n,({key:r,value:e,parent:s,isNode:f})=>{if(c(e)==="array"&&e.length!==1){let i='Invalid "array" elements in schema definition.';throw new Error(i)}if(f){if(!Object.keys(e).length){let i="Invalid empty object in schema definition.";throw new Error(i)}if(e.type&&!ct.includes(e.type)){let i=`Invalid "type" key in schema definition: "${e.type}".\r Allowed types: "${ct.join('", "')}".`;throw new Error(i)}if(e.default!==void 0){let i=c(e.default),l=i==="function"?c(e.default()):i;if(e.required!==void 0){let d='Invalid combination of "default" and "required" keys in schema definition.';throw new Error(d)}if(e.type==="date"&&l!=="number"||e.type!=="date"&&e.type!==l){let d=`Invalid type of "default" key in schema definition. Expexted type is "${e.type}".`;throw new Error(d)}}}else{if(r!=="$ref"&&!s.type){let i='Missing "type" key in schema definition.';throw new Error(i)}if(!dt.includes(r)){let i=`Invalid key in schema definition: "${r}".\r Allowed keys: "${dt.join('", "')}".`;throw new Error(i)}}}),n},K=(t,n)=>{let r={};if(t===void 0){if(E.get("strict")){let e='Invalid "undefined" source object.';throw new Error(e)}return}if(c(n)!=="object"){if(E.get("strict")){let e='Invalid "object" type of schema definition.';throw new Error(e)}return}return D(n,({value:e,path:s,parent:f})=>{let i=c(e.default)==="function"?e.default():e.default,l=M(t,s),d=l===void 0&&i!==void 0?i:l,m=e.type||c(e),v=c(f),$=c(d),T=m==="date"?$==="number":m===$;if(m==="array"&&I(r,s,[]),!(d===void 0||v==="array")){if(E.get("strict")&&!T){let k=`Invalid type of "${s}" value. Expected type is "${m}".`;throw new Error(k)}if(e.$ref){let k={_ref:{collection:e?.$ref,id:d?._id}};I(r,s.replace(/\.\$ref$/g,""),k);return}switch(m==="object"&&$==="object"&&I(r,s,{}),m==="array"&&$==="array"&&d.forEach((k,B)=>{let L=[s,B].join("."),{itemValue:W}=K({itemValue:k},{itemValue:e[0]});I(r,L,W)}),e.type){case"string":I(r,s,String(d));break;case"number":I(r,s,Number(d)||0);break;case"boolean":I(r,s,!!d);break;case"date":I(r,s,tt(d)||0);break}}}),r};var Rt=(t="",n={})=>{let r=Object.keys(n).length>0;if(/^[a-z0-9_-]+$/.test(t)==!1){let o=`Collection name (${t}) must contain only small caps, numbers, hypens or underscores.`;throw new Error(o)}if(["__proto__","prototype","constructor"].includes(t)){let o=`Collection name (${t}) must not be "__proto__", "prototype" or "constructor".`;throw new Error(o)}if(t.endsWith("s")===!1){let o=`Collection name (${t}) must be plural. For example: users, categories, products.`;throw new Error(o)}h[t]||(h[t]=new Map);let e=async(o,a=!1,p=!1)=>{if(c(o)!=="object"){let S="Invalid object type of query.";throw new Error(S)}p&&await O("pre",t,"find",o);let y=Y(h[t],o),u=a?x(y):y;return p&&await O("post",t,"find",u),u},s=async o=>{o=c(o)==="array"?o:[o],await O("pre",t,"create",o);let a=o.map(u=>r?K(u,n):u);D(n,({key:u,value:S})=>{if(S.required)for(let C of a){let b=M(C,u)||M(C,u);if(b==null)throw new Error(`"${u}" field is required.`)}});let p=[];D(n,({key:u,value:S})=>{S.unique&&p.push(u)});for(let u of p){let S=a.map(b=>M(b,u)).filter(b=>b!=null);for(let b of S)if(Y(h[t],{[u]:b}).length>0)throw new Error(`"${u}" field must be unique.`);let C=new Set;for(let b of S){if(C.has(b))throw new Error(`"${u}" field must be unique among new items.`);C.add(b)}}let y=a.filter(u=>Object.keys(u).length>0).map(u=>{let S=J();return u._id=U(),u._version=1,E.get("defaultFields")&&(u._created=S,u._updated=S),u});if(y.length>0){for(let u of y)h[t].set(u._id,g(u));R.onInsert(t,y)}return await O("post",t,"create",y),y},f=async(o,a,p)=>{if(o=c(o)==="array"?o:[o],c(a)!=="object")throw new Error("Invalid object type of updates.");let y=0,u=J(),S=p?"replace":"update";await O("pre",t,S,o);let C=r?K(a,n):a;D(n,({key:w,value:P})=>{if(P.unique){let A=[];for(let H of o){let q=M(C,w);if(q==null)continue;if(Y(h[t],{[w]:q,_id:{$ne:H._id}}).length>0)throw new Error(`"${w}" field must be unique.`);A.push(q)}let j=new Set;for(let H of A){if(j.has(H))throw new Error(`"${w}" field must be unique.`);j.add(H)}}if(P.required)for(let A of o){let j;if(p?j=M(C,w):(j=M(C,w),j===void 0&&(j=M(A,w))),c(a.$unset)==="object"&&a.$unset[w])throw new Error(`"${w}" field is required and cannot be unset.`);if(j==null)throw new Error(`"${w}" field is required.`)}});let b=o.map(w=>{let P=0;if(p?(w={...{_id:w._id,_created:w._created},...C},P=1):D(C,({value:A,path:j,isNode:H})=>{H||j.startsWith("$")||M(w,j)!==A&&(P++,I(w,j,A))}),c(a.$unset)==="object"){if(p)throw new Error("Cannot unset fields in replace operation.");for(let A in a.$unset)M(w,A)!==void 0&&(P++,I(w,A,void 0))}return P&&(w._version=(w._version||1)+1,E.get("defaultFields")&&(w._created??=u,w._updated=u),y++),w});if(y>0){for(let w of b)h[t].has(w._id)&&h[t].set(w._id,g(w));R.onUpdate(t,b)}return await O("post",t,S,b),b},i=async o=>{if(o&&o.length>0){await O("pre",t,"delete",o);for(let a of o)a&&a._id&&h[t].delete(a._id);return R.onDelete(t,o),await O("post",t,"delete",o),o}},l=async o=>{if(c(o)!=="object"){let p="Invalid object type of item.";throw new Error(p)}let a=await s(o);return x(a[0])},d=async o=>{if(c(o)!=="array"){let p="Invalid array type of items.";throw new Error(p)}let a=await s(o);return x(a)},m=async(o,a,p=!1)=>{let y=await T({_id:o}),u=await f(y,a,p);return x(u[0])},v=async(o,a,p=!1)=>{let y=await T(o),u=await f(y,a,p);return x(u[0])},$=async(o,a,p=!1)=>{let y=await e(o),u=await f(y,a,p);return x(u)},T=async(o,a=!1,p=!1)=>{let y=await e(o,!1,p);return a?x(y[0]):y[0]},k=async(o,a=!1,p=!1)=>{if(!o||c(o)!=="string"){let u="Invalid string type of id.";throw new Error(u)}let y=await e({_id:o},!1,p);return a?x(y[0]):y[0]},B=async o=>(await e(o)).length,L=async o=>await B(o)>0,W=async o=>{let a=await k(o)||null,p=await i([a]);return x(p[0])},wt=async o=>{let a=await T(o)||null,p=await i([a]);return x(p[0])},yt=async o=>{let a=await e(o);if(a&&a.length>0){let p=await i(a);return x(p)}return[]},Q=async(o,a)=>{await O("pre",t,"read",o);let p=await a();return await O("post",t,"read",p),p};return{pre:(o,a)=>Z("pre",t,o,a),post:(o,a)=>Z("post",t,o,a),find:async o=>Q(o,()=>e(o,!0,!0)),findOne:async o=>Q(o,()=>T(o,!0,!0)),findById:async o=>Q({_id:o},()=>k(o,!0,!0)),findByIdAndReplace:async(o,a)=>await m(o,a,!0),findByIdAndUpdate:async(o,a)=>await m(o,a),findByIdAndDelete:W,insertOne:l,insertMany:d,updateOne:async(o,a)=>await v(o,a),updateMany:async(o,a)=>await $(o,a),replaceOne:async(o,a)=>await v(o,a,!0),replaceMany:async(o,a)=>await $(o,a,!0),deleteOne:wt,deleteMany:yt,count:B,exists:L}},lt=Rt;var Ut={...N,...z,...G,...et},pt=!1,Bt=async(t=E.getDefaultConfig(),n=null,r=null)=>{if(!pt)pt=!0,E.setConfig(t),await ot({storageAdapter:n,backupAdapter:r});else if(E.get("strict")){let e="Stormflow is already initialized.";throw new Error(e)}},qt={start:Bt,getConfig:E.getConfig,setConfig:E.setConfig,Schema:ut,model:lt,utils:Ut};