modelence 0.5.1-dev.4 → 0.5.1

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.
@@ -0,0 +1,3 @@
1
+ var s="module",i="modelence",n="0.5.1",o="The Node.js Framework for Real-Time MongoDB Apps",p="dist/index.js",r="dist/global.d.ts",d={".":"./dist/index.js","./client":"./dist/client.js","./server":"./dist/server.js","./telemetry":"./dist/telemetry.js","./mongodb":"./dist/mongo.js"},c=["dist","dist/bin"],l={modelence:"./dist/bin/modelence.js"},m={build:"tsup",dev:"tsup --watch",prepublishOnly:"npm run build",test:'echo "Error: no test specified" && exit 1',postversion:"git push && git push --tags"},a={type:"git",url:"git+https://github.com/modelence/modelence.git"},u="Modelence",y="SEE LICENSE IN LICENSE",g={url:"https://github.com/modelence/modelence/issues"},h="https://modelence.com",b={"@types/archiver":"^6.0.3","@types/bcrypt":"^5.0.2","@types/express":"^5.0.0","@types/fs-extra":"^11.0.4","@types/node":"^22.5.1","@types/react":"^19.0.0","@types/react-dom":"^19.0.1","@typescript-eslint/eslint-plugin":"^8.17.0","@typescript-eslint/parser":"^8.17.0",react:"^19.0.0","react-dom":"^19.0.0",typescript:"^5.7.2"},v={"@octokit/rest":"^20.0.2","@vitejs/plugin-react":"^4.3.4",archiver:"^7.0.1",bcrypt:"^5.1.1",commander:"^12.0.0",dotenv:"^16.4.5","elastic-apm-node":"^4.8.0",express:"^4.21.0","fs-extra":"^11.2.0",jiti:"^2.4.2",mongodb:"^6.8.1",open:"^10.1.0",tsup:"^8.3.6",tsx:"^4.19.3",vite:"^6.0.3","vite-plugin-eslint":"^1.8.1",winston:"^3.15.0","winston-elasticsearch":"^0.19.0",zod:"^3.23.8",zustand:"^5.0.2"},j={react:">=18.0.0","react-dom":">=18.0.0"},x={type:s,name:i,version:n,description:o,main:p,types:r,exports:d,files:c,bin:l,scripts:m,repository:a,author:u,license:y,bugs:g,homepage:h,devDependencies:b,dependencies:v,peerDependencies:j};
2
+ export{u as author,l as bin,g as bugs,x as default,v as dependencies,o as description,b as devDependencies,d as exports,c as files,h as homepage,y as license,p as main,i as name,j as peerDependencies,a as repository,m as scripts,s as type,r as types,n as version};//# sourceMappingURL=package-OWDOQ74X.js.map
3
+ //# sourceMappingURL=package-OWDOQ74X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../package.json"],"names":["type","name","version","description","main","types","exports","files","bin","scripts","repository","author","license","bugs","homepage","devDependencies","dependencies","peerDependencies","package_default"],"mappings":"AACE,IAAAA,EAAQ,QACRC,CAAAA,CAAAA,CAAQ,YACRC,CAAW,CAAA,OAAA,CACXC,EAAe,kDACfC,CAAAA,CAAAA,CAAQ,gBACRC,CAAS,CAAA,kBAAA,CACTC,EAAW,CACT,GAAA,CAAK,kBACL,UAAY,CAAA,kBAAA,CACZ,WAAY,kBACZ,CAAA,aAAA,CAAe,qBACf,CAAA,WAAA,CAAa,iBACf,CACAC,CAAAA,CAAAA,CAAS,CACP,MACA,CAAA,UACF,EACAC,CAAO,CAAA,CACL,UAAa,yBACf,CAAA,CACAC,EAAW,CACT,KAAA,CAAS,OACT,GAAO,CAAA,cAAA,CACP,eAAkB,eAClB,CAAA,IAAA,CAAQ,2CACR,CAAA,WAAA,CAAe,6BACjB,CACAC,CAAAA,CAAAA,CAAc,CACZ,IAAQ,CAAA,KAAA,CACR,IAAO,gDACT,CAAA,CACAC,EAAU,WACVC,CAAAA,CAAAA,CAAW,yBACXC,CAAQ,CAAA,CACN,IAAO,+CACT,CAAA,CACAC,EAAY,uBACZC,CAAAA,CAAAA,CAAmB,CACjB,iBAAA,CAAmB,SACnB,eAAiB,CAAA,QAAA,CACjB,iBAAkB,QAClB,CAAA,iBAAA,CAAmB,UACnB,aAAe,CAAA,SAAA,CACf,eAAgB,SAChB,CAAA,kBAAA,CAAoB,UACpB,kCAAoC,CAAA,SAAA,CACpC,4BAA6B,SAC7B,CAAA,KAAA,CAAS,UACT,WAAa,CAAA,SAAA,CACb,UAAc,CAAA,QAChB,EACAC,CAAgB,CAAA,CACd,gBAAiB,SACjB,CAAA,sBAAA,CAAwB,SACxB,QAAY,CAAA,QAAA,CACZ,OAAU,QACV,CAAA,SAAA,CAAa,UACb,MAAU,CAAA,SAAA,CACV,mBAAoB,QACpB,CAAA,OAAA,CAAW,UACX,UAAY,CAAA,SAAA,CACZ,IAAQ,CAAA,QAAA,CACR,QAAW,QACX,CAAA,IAAA,CAAQ,UACR,IAAQ,CAAA,QAAA,CACR,IAAO,SACP,CAAA,IAAA,CAAQ,SACR,oBAAsB,CAAA,QAAA,CACtB,QAAW,SACX,CAAA,uBAAA,CAAyB,UACzB,GAAO,CAAA,SAAA,CACP,QAAW,QACb,CAAA,CACAC,CAAoB,CAAA,CAClB,MAAS,UACT,CAAA,WAAA,CAAa,UACf,CA7EFC,CAAAA,CAAAA,CAAA,CACE,IAAAlB,CAAAA,CAAAA,CACA,KAAAC,CACA,CAAA,OAAA,CAAAC,EACA,WAAAC,CAAAA,CAAAA,CACA,KAAAC,CACA,CAAA,KAAA,CAAAC,EACA,OAAAC,CAAAA,CAAAA,CAOA,KAAAC,CAAAA,CAAAA,CAIA,IAAAC,CAGA,CAAA,OAAA,CAAAC,EAOA,UAAAC,CAAAA,CAAAA,CAIA,OAAAC,CACA,CAAA,OAAA,CAAAC,EACA,IAAAC,CAAAA,CAAAA,CAGA,SAAAC,CACA,CAAA,eAAA,CAAAC,EAcA,YAAAC,CAAAA,CAAAA,CAsBA,iBAAAC,CAIF","file":"package-OWDOQ74X.js","sourcesContent":["{\n \"type\": \"module\",\n \"name\": \"modelence\",\n \"version\": \"0.5.1\",\n \"description\": \"The Node.js Framework for Real-Time MongoDB Apps\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/global.d.ts\",\n \"exports\": {\n \".\": \"./dist/index.js\",\n \"./client\": \"./dist/client.js\",\n \"./server\": \"./dist/server.js\",\n \"./telemetry\": \"./dist/telemetry.js\",\n \"./mongodb\": \"./dist/mongo.js\"\n },\n \"files\": [\n \"dist\",\n \"dist/bin\"\n ],\n \"bin\": {\n \"modelence\": \"./dist/bin/modelence.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n \"postversion\": \"git push && git push --tags\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/modelence/modelence.git\"\n },\n \"author\": \"Modelence\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"bugs\": {\n \"url\": \"https://github.com/modelence/modelence/issues\"\n },\n \"homepage\": \"https://modelence.com\",\n \"devDependencies\": {\n \"@types/archiver\": \"^6.0.3\",\n \"@types/bcrypt\": \"^5.0.2\",\n \"@types/express\": \"^5.0.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/node\": \"^22.5.1\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.1\",\n \"@typescript-eslint/eslint-plugin\": \"^8.17.0\",\n \"@typescript-eslint/parser\": \"^8.17.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"typescript\": \"^5.7.2\"\n },\n \"dependencies\": {\n \"@octokit/rest\": \"^20.0.2\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"archiver\": \"^7.0.1\",\n \"bcrypt\": \"^5.1.1\",\n \"commander\": \"^12.0.0\",\n \"dotenv\": \"^16.4.5\",\n \"elastic-apm-node\": \"^4.8.0\",\n \"express\": \"^4.21.0\",\n \"fs-extra\": \"^11.2.0\",\n \"jiti\": \"^2.4.2\",\n \"mongodb\": \"^6.8.1\",\n \"open\": \"^10.1.0\",\n \"tsup\": \"^8.3.6\",\n \"tsx\": \"^4.19.3\",\n \"vite\": \"^6.0.3\",\n \"vite-plugin-eslint\": \"^1.8.1\",\n \"winston\": \"^3.15.0\",\n \"winston-elasticsearch\": \"^0.19.0\",\n \"zod\": \"^3.23.8\",\n \"zustand\": \"^5.0.2\"\n },\n \"peerDependencies\": {\n \"react\": \">=18.0.0\",\n \"react-dom\": \">=18.0.0\"\n }\n}\n"]}
package/dist/server.js CHANGED
@@ -1,3 +1,3 @@
1
- import {a as a$3}from'./chunk-DN5SVAO2.js';import {a as a$4,b as b$2}from'./chunk-EQLDF7OO.js';import {a as a$1}from'./chunk-R7MPLJMA.js';import {b as b$1,e,d,c,f as f$1,g as g$1,a as a$2,h,j,k}from'./chunk-QN73CYII.js';export{a as getConfig}from'./chunk-QN73CYII.js';import ze from'dotenv';import nt from'http';import q from'express';import y,{z as z$1}from'zod';import {ObjectId,MongoClient}from'mongodb';export{ObjectId}from'mongodb';import {randomBytes}from'crypto';import st from'os';import lt from'bcrypt';import {createServer,defineConfig}from'vite';import wt from'@vitejs/plugin-react';import L from'path';import bt from'fs';function Fe(){return typeof window!="object"}function w(){if(!Fe())throw new Error("This function can only be called on the server")}var oe=new Map,C={authenticated:null,unauthenticated:null};function ne(t,e){C.authenticated=e.authenticated,C.unauthenticated=e.unauthenticated;for(let[o,n]of Object.entries(t))oe.set(o,n);}function v(){return C.unauthenticated?[C.unauthenticated]:[]}function re(){return C.authenticated?[C.authenticated]:[]}function ie(t,e){let o=e.find(n=>!Le(t,n));if(o)throw new Error(`Access denied - missing permission: '${o}'`)}function Le(t,e){for(let o of t){let n=oe.get(o);if(n&&n.permissions.includes(e))return true}return false}var N={};function U(t,e){return w(),le(t),I("query",t,e)}function se(t,e){return w(),le(t),I("mutation",t,e)}function ae(t,e){return w(),de(t),I("query",t,e)}function ce(t,e){return w(),de(t),I("mutation",t,e)}function le(t){if(t.toLowerCase().startsWith("_system."))throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${t})`)}function de(t){if(!t.toLowerCase().startsWith("_system."))throw new Error(`System method name must start with a prefix: '_system.' (${t})`)}function I(t,e,o){if(w(),N[e])throw new Error(`Method with name '${e}' is already defined.`);let n=typeof o=="function"?o:o.handler,i=typeof o=="function"?[]:o.permissions??[];N[e]={type:t,name:e,handler:n,permissions:i};}async function ue(t,e,o){w();let n=N[t];if(!n)throw new Error(`Method with name '${t}' is not defined.`);let{type:i,handler:r}=n,s=j("method",`method:${t}`,{type:i,args:e}),c;try{ie(o.roles,n.permissions),c=await r(e,o);}catch(h){throw s.end("error"),h}return s.end(),c}var p=class{constructor(e,{stores:o=[],queries:n={},mutations:i={},routes:r=[],cronJobs:s={},configSchema:c={}}){this.name=e,this.stores=o,this.queries=n,this.mutations=i,this.routes=r,this.cronJobs=s,this.configSchema=c;}};var f=class{constructor(e,o){this.name=e,this.schema=o.schema,this.methods=o.methods,this.indexes=o.indexes;}getName(){return this.name}getSchema(){return this.schema}init(e){if(this.collection)throw new Error(`Collection ${this.name} is already initialized`);this.client=e,this.collection=this.client.db().collection(this.name);}async createIndexes(){this.indexes.length>0&&await this.requireCollection().createIndexes(this.indexes);}wrapDocument(e){return this.methods?Object.create(null,Object.getOwnPropertyDescriptors({...e,...this.methods})):e}requireCollection(){if(!this.collection)throw new Error(`Collection ${this.name} is not provisioned`);return this.collection}requireClient(){if(!this.client)throw new Error("Database is not connected");return this.client}async findOne(e,o){let n=await this.requireCollection().findOne(e,o);return n?this.wrapDocument(n):null}async requireOne(e,o,n){let i=await this.findOne(e,o);if(!i)throw n?n():new Error(`Record not found in ${this.name}`);return i}find(e,o){let n=this.requireCollection().find(e);return o?.sort&&n.sort(o.sort),o?.limit&&n.limit(o.limit),o?.skip&&n.skip(o.skip),n}async findById(e){let o=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(o)}async requireById(e,o){let n=await this.findById(e);if(!n)throw o?o():new Error(`Record with id ${e} not found in ${this.name}`);return n}async fetch(e,o){return (await this.find(e,o).toArray()).map(this.wrapDocument.bind(this))}async insertOne(e){return await this.requireCollection().insertOne(e)}async insertMany(e){return await this.requireCollection().insertMany(e)}async updateOne(e,o){let n=typeof e=="string"?{_id:new ObjectId(e)}:e;return await this.requireCollection().updateOne(n,o)}async upsertOne(e,o){return await this.requireCollection().updateOne(e,o,{upsert:true})}async updateMany(e,o,n){return await this.requireCollection().updateMany(e,o,n)}async upsertMany(e,o){return await this.requireCollection().updateMany(e,o,{upsert:true})}async deleteOne(e){return await this.requireCollection().deleteOne(e)}async deleteMany(e){return await this.requireCollection().deleteMany(e)}aggregate(e,o){return this.requireCollection().aggregate(e,o)}bulkWrite(e){return this.requireCollection().bulkWrite(e)}getDatabase(){return this.requireClient().db()}rawCollection(){return this.requireCollection()}async renameFrom(e,o){let n=this.getDatabase();if(!this.collection||!n)throw new Error(`Store ${this.name} is not provisioned`);if((await n.listCollections({name:e}).toArray()).length===0)throw new Error(`Collection ${e} not found`);if((await n.listCollections({name:this.name}).toArray()).length>0)throw new Error(`Collection ${this.name} already exists`);await n.collection(e).rename(this.name,o);}};var We=z$1.string.bind(z$1),Ke=z$1.number.bind(z$1),Ve=z$1.date.bind(z$1),He=z$1.boolean.bind(z$1),Ze=z$1.array.bind(z$1),Qe=z$1.object.bind(z$1),Ge=z$1.enum.bind(z$1),a={string:We,number:Ke,date:Ve,boolean:He,array:Ze,object:Qe,enum:Ge,objectId(){return z$1.instanceof(ObjectId)},userId(){return z$1.instanceof(ObjectId)},ref(t){return z$1.instanceof(ObjectId)},union:z$1.union.bind(z$1),infer(t){return {}}};var x=new f("_modelenceSessions",{schema:{authToken:a.string(),createdAt:a.date(),expiresAt:a.date(),userId:a.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function pe(t){let e=t?await x.findOne({authToken:t}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await Xe()}async function fe(t,e){await x.updateOne({authToken:t},{$set:{userId:e}});}async function he(t){await x.updateOne({authToken:t},{$set:{userId:null}});}async function Xe(){let t=randomBytes(32).toString("base64url"),e=Date.now(),o=new Date(e+a$1.days(7));return await x.insertOne({authToken:t,createdAt:new Date(e),expiresAt:o,userId:null}),{authToken:t,expiresAt:o,userId:null}}async function et(t){let e=Date.now(),o=new Date(e+a$1.days(7));await x.updateOne({authToken:t.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:o}});}var ge=new p("_system.session",{stores:[x],mutations:{init:async function(t,{session:e,user:o}){return {session:e,user:o,configs:b$1()}},heartbeat:async function(t,{session:e}){e&&await et(e);}}});var u=new f("_modelenceUsers",{schema:{handle:a.string(),emails:a.array(a.object({address:a.string(),verified:a.boolean()})).optional(),createdAt:a.date(),authMethods:a.object({password:a.object({hash:a.string()}).optional(),google:a.object({id:a.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}}]});async function ye(t){let e=await pe(t),o=e.userId?await u.findOne({_id:new ObjectId(e.userId)}):null,n=o?{id:o._id.toString(),handle:o.handle}:null,i=n?re():v();return {user:n,session:e,roles:i}}function we(t){return async(e,o)=>{try{let n=await t({query:e.query,body:e.body,params:e.params,headers:e.headers,cookies:e.cookies,req:e});o.status(n.status||200),n.headers&&Object.entries(n.headers).forEach(([i,r])=>{o.setHeader(i,r);}),o.send(n.data);}catch(n){n instanceof a$4||n instanceof b$2?o.status(n.status).send(n.message):(console.error(`Error in route handler: ${e.path}`),console.error(n),o.status(500).send(String(n)));}}}var g=null;async function be(){if(g)return g;let t=D();if(!t)throw new Error("MongoDB URI is not set");g=new MongoClient(t,{maxPoolSize:20});try{return await g.connect(),await g.db("admin").command({ping:1}),console.log("Pinged your deployment. You successfully connected to MongoDB!"),g}catch(e){throw console.error(e),g=null,e}}function D(){let t=a$2("_system.mongodbUri");return t?String(t):void 0}function Ce(){return g}function rt(t,e){for(let o of e)for(let n of o.routes){let{path:i,handlers:r}=n;Object.entries(r).forEach(([s,c])=>{t[s](i,we(c));});}}async function xe(t,{combinedModules:e}){let o=q();o.use(q.json()),o.use(q.urlencoded({extended:true})),o.post("/api/_internal/method/:methodName(*)",async(r,s)=>{let{methodName:c}=r.params,h=await it(r);try{let d=await ue(c,r.body.args,h);s.json({data:d,typeMap:a$3(d)});}catch(d){if(console.error(`Error in method ${c}:`,d),d instanceof Error&&d?.constructor?.name==="ZodError"&&"errors"in d){let S=d.flatten(),E=Object.entries(S.fieldErrors).map(([j,P])=>`${j}: ${(P??[]).join(", ")}`).join("; "),A=S.formErrors.join("; "),k=[E,A].filter(Boolean).join("; ");s.status(400).send(k);}else s.status(500).send(d instanceof Error?d.message:String(d));}}),rt(o,e),await t.init(),t.middlewares&&o.use(t.middlewares()),o.all("*",(r,s)=>t.handler(r,s)),process.on("unhandledRejection",(r,s)=>{console.error("Unhandled Promise Rejection:"),console.error(r instanceof Error?r.stack:r),console.error("Promise:",s);}),process.on("uncaughtException",r=>{console.error("Uncaught Exception:"),console.error(r.stack),console.trace("Full application stack:");});let n=nt.createServer(o),i=process.env.PORT||3e3;n.listen(i,()=>{h("Application started",{source:"app"}),console.log(`Application started on port ${i}`);});}async function it(t){let e=y.string().nullish().transform(r=>r??null).parse(t.body.authToken),o=y.object({screenWidth:y.number(),screenHeight:y.number(),windowWidth:y.number(),windowHeight:y.number(),pixelRatio:y.number(),orientation:y.string().nullable()}).parse(t.body.clientInfo),n={ip:t.ip||t.socket.remoteAddress,userAgent:t.get("user-agent"),acceptLanguage:t.get("accept-language"),referrer:t.get("referrer")};if(!!D()){let{session:r,user:s,roles:c}=await ye(e);return {clientInfo:o,connectionInfo:n,session:r,user:s,roles:c}}return {clientInfo:o,connectionInfo:n,session:null,user:null,roles:v()}}async function Se({configSchema:t,cronJobsMetadata:e,stores:o}){let n=process.env.MODELENCE_CONTAINER_ID;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set");try{let i=Object.values(o).map(s=>({name:s.getName(),schema:s.getSchema(),collections:[s.getName()]})),r=await B("/api/connect","POST",{hostname:st.hostname(),containerId:n,dataModels:i,configSchema:t,cronJobsMetadata:e});if(r.status==="error")throw new Error(r.error);return console.log("Successfully connected to Modelence Cloud"),r}catch(i){throw console.error("Unable to connect to Modelence Cloud:",i),i}}async function Ee(){return await B("/api/configs","GET")}async function Me(){return await B("/api/sync","POST",{containerId:process.env.MODELENCE_CONTAINER_ID})}async function B(t,e,o){let{MODELENCE_SERVICE_ENDPOINT:n,MODELENCE_SERVICE_TOKEN:i}=process.env;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set");let r=await fetch(`${n}${t}`,{method:e,headers:{Authorization:`Bearer ${i}`,...o?{"Content-Type":"application/json"}:{}},body:o?JSON.stringify(o):void 0});if(!r.ok){let s=await r.text();try{let c=JSON.parse(s);throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${r.status}, ${c?.error}`)}catch{throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${r.status}, ${s}`)}}return await r.json()}var z=false,at=a$1.seconds(10);function De(){setInterval(async()=>{if(!z){z=true;try{await Me();}catch(t){console.error("Error syncing status",t);}try{await ct();}catch(t){console.error("Error syncing config",t);}z=false;}},at);}async function ct(){let{configs:t}=await Ee();c(t);}async function Te(t,{user:e}){let o=z$1.string().email().parse(t.email),n=z$1.string().min(8,{message:"Password must contain at least 8 characters"}).parse(t.password),i=await u.findOne({"emails.address":o},{collation:{locale:"en",strength:2}});if(i){let c=i.emails?.find(h=>h.address===o);throw new Error(`User with email already exists: ${c?.address}`)}let r=await lt.hash(n,10);return (await u.insertOne({handle:o,emails:[{address:o,verified:false}],createdAt:new Date,authMethods:{password:{hash:r}}})).insertedId}async function Ie(t,{user:e,session:o}){if(!o)throw new Error("Session is not initialized");let n=z$1.string().email().parse(t.email),i=z$1.string().parse(t.password),r=await u.findOne({"emails.address":n},{collation:{locale:"en",strength:2}}),s=r?.authMethods?.password?.hash;if(!r||!s||!await lt.compare(i,s))throw ve();return await fe(o.authToken,r._id),{user:{id:r._id,handle:r.handle}}}async function _e(t,{user:e,session:o}){if(!o)throw new Error("Session is not initialized");await he(o.authToken);}function ve(){return new Error("Incorrect email/password combination")}async function Ae(t,{user:e}){if(!e)throw new Error("Not authenticated");let o=await u.requireById(e.id);return {handle:o.handle,emails:o.emails,authMethods:Object.keys(o.authMethods||{})}}var ke=new p("_system.user",{stores:[u],queries:{getOwnProfile:Ae},mutations:{signupWithPassword:Te,loginWithPassword:Ie,logout:_e}});var _=new f("_modelenceMigrations",{schema:{version:a.number(),appliedAt:a.date()},indexes:[{key:{version:1},unique:true}]});async function je(t){if(t.length===0)return;let e=t.map(({version:r})=>r),o=await _.fetch({version:{$in:e}}),n=new Set(o.map(({version:r})=>r)),i=t.filter(({version:r})=>!n.has(r));if(i.length!==0){console.log(`Running migrations (${i.length})...`);for(let{version:r,description:s,handler:c}of i)console.log(`Running migration v${r}: ${s}`),await _.insertOne({version:r,appliedAt:new Date}),await c(),console.log(`Migration v${r} complete`);}}var Pe=new p("_system.migration",{stores:[_]});var ut=a$1.minutes(1),mt=a$1.seconds(10),b={},F,R=new f("_modelenceCronJobs",{schema:{alias:a.string(),lastStartDate:a.date().optional(),lock:a.object({containerId:a.string(),acquireDate:a.date()}).optional()},indexes:[{key:{alias:1},unique:true,background:true}]});function Ne(t,{description:e="",interval:o,timeout:n=ut,handler:i}){if(b[t])throw new Error(`Duplicate cron job declaration: '${t}' already exists`);if(F)throw new Error(`Unable to add a cron job - cron jobs have already been initialized: [${t}]`);if(o<a$1.seconds(5))throw new Error(`Cron job interval should not be less than 5 second [${t}]`);if(n>a$1.days(1))throw new Error(`Cron job timeout should not be longer than 1 day [${t}]`);b[t]={alias:t,params:{description:e,interval:o,timeout:n},handler:i,state:{isRunning:false}};}async function Ue(){if(F)throw new Error("Cron jobs already started");let t=Object.keys(b);if(t.length>0){let e={alias:{$in:t}},o=await R.findOne({...e,"lock.containerId":{$exists:true}});await R.upsertMany(e,{$set:{lock:{containerId:process.env.MODELENCE_CONTAINER_ID||"unknown",acquireDate:new Date}}}),o&&await pt(mt);let n=await R.fetch(e),i=Date.now();n.forEach(r=>{let s=b[r.alias];s&&(s.state.scheduledRunTs=r.lastStartDate?r.lastStartDate.getTime()+s.params.interval:i);}),Object.values(b).forEach(r=>{r.state.scheduledRunTs||(r.state.scheduledRunTs=i);}),F=setInterval(ft,a$1.seconds(1));}}function pt(t){return new Promise(e=>setTimeout(e,t))}async function ft(){let t=Date.now();Object.values(b).forEach(async e=>{let{params:o,state:n}=e;if(n.isRunning){n.startTs&&n.startTs+o.timeout<t&&(n.isRunning=false);return}n.scheduledRunTs&&n.scheduledRunTs<=t&&await ht(e);});}async function ht(t){let{alias:e,params:o,handler:n,state:i}=t;i.isRunning=true,i.startTs=Date.now();let r=j("cron",`cron:${e}`);n().then(()=>{$e(i,o),r.end("success");}).catch(s=>{$e(i,o),k(s),r.end("error"),console.error(`Error in cron job '${e}':`,s);}),await R.updateOne({alias:e},{$set:{lastStartDate:new Date(i.startTs)}});}function $e(t,e){t.scheduledRunTs=t.startTs?t.startTs+e.interval:Date.now(),t.startTs=void 0,t.isRunning=false;}function Je(){return Object.values(b).map(({alias:t,params:e})=>({alias:t,description:e.description,interval:e.interval,timeout:e.timeout}))}var qe=new p("_system.cron",{stores:[R]});var W=class{async init(){this.isDev()&&(console.log("Starting Vite dev server..."),this.viteServer=await createServer({...defineConfig(await xt()),server:{middlewareMode:true},root:"./src/client"}));}middlewares(){return this.isDev()?this.viteServer?.middlewares??[]:[q.static("./.modelence/build/client")]}handler(e,o){if(this.isDev())try{o.sendFile("index.html",{root:"./src/client"});}catch(n){console.error("Error serving index.html:",n),o.status(500).send("Internal Server Error");}else o.sendFile("index.html",{root:"./.modelence/build/client"});}isDev(){return process.env.NODE_ENV!=="production"}};async function xt(){let t=process.cwd(),e=[".eslintrc.js",".eslintrc.json",".eslintrc","eslint.config.js",".eslintrc.yml",".eslintrc.yaml"].find(n=>bt.existsSync(L.join(t,n))),o=[wt(),St()];if(e){let n=(await import('vite-plugin-eslint')).default;o.push(n({failOnError:false,include:["src/**/*.js","src/**/*.jsx","src/**/*.ts","src/**/*.tsx"],cwd:t,overrideConfigFile:L.resolve(t,e)}));}return {plugins:o,root:t,build:{outDir:".modelence/build/client",emptyOutDir:true},server:{proxy:{"/api":"http://localhost:4000"},headers:{"Cache-Control":"no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0",Pragma:"no-cache",Expires:"0"},hmr:{port:0}},resolve:{alias:{"@":L.resolve(t,"src")}}}}function St(){return {name:"modelence-asset-handler",async transform(t,e){if(/\.(png|jpe?g|gif|svg|mpwebm|ogg|mp3|wav|flac|aac)$/.test(e))return process.env.NODE_ENV==="development",t},async generateBundle(t,e){}}}var Be=new W;async function Et({modules:t=[],roles:e$1={},defaultRoles:o={},server:n=Be,migrations:i=[]}){ze.config(),ze.config({path:".modelence.env"});let r=!!process.env.MODELENCE_SERVICE_ENDPOINT,s=process.env.MODELENCE_CRON_ENABLED==="true";_t().then(()=>{}).catch(()=>{});let c$1=[ke,ge,qe,Pe],h=[...c$1,...t];e(),Dt(c$1),Mt(t),ne(e$1,o);let d$1=Tt(h);d(d$1??{});let T=Rt(h);if(s&&Ot(h),r){let{configs:E,environmentId:A,appAlias:k,environmentAlias:j,telemetry:P}=await Se({configSchema:d$1,cronJobsMetadata:s?Je():void 0,stores:T});c(E),f$1({environmentId:A,appAlias:k,environmentAlias:j,telemetry:P});}else c(It());let S=D();if(S&&(await be(),vt(T)),s&&await je(i),S)for(let E of T)E.createIndexes();r&&(await g$1(),De()),s&&Ue().catch(console.error),await xe(n,{combinedModules:h});}function Mt(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))U(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))se(`${e.name}.${o}`,n);}}function Dt(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))ae(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))ce(`${e.name}.${o}`,n);}}function Rt(t){return t.flatMap(e=>e.stores)}function Tt(t){let e={};for(let o of t)for(let[n,i]of Object.entries(o.configSchema)){let r=`${o.name}.${n}`;if(r in e)throw new Error(`Duplicate config schema key: ${r} (${o.name})`);e[r]=i;}return e}function Ot(t){for(let e of t)for(let[o,n]of Object.entries(e.cronJobs))Ne(`${e.name}.${o}`,n);}function vt(t){let e=Ce();if(!e)throw new Error("Failed to initialize stores: MongoDB client not initialized");for(let o of t)o.init(e);}function It(){let t=[];return process.env.MONGODB_URI&&t.push({key:"_system.mongodbUri",type:"string",value:process.env.MONGODB_URI}),t}async function _t(){if(process.env.MODELENCE_TRACKING_ENABLED!=="false"){let e=process.env.MODELENCE_SERVICE_ENDPOINT??"https://cloud.modelence.com",o=await import('./package-WATZNRLZ.js');await fetch(`${e}/api/track/app-start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:o.default.version})});}}
1
+ import {a as a$3}from'./chunk-DN5SVAO2.js';import {a as a$4,b as b$2}from'./chunk-EQLDF7OO.js';import {a as a$1}from'./chunk-R7MPLJMA.js';import {b as b$1,e,d,c,f as f$1,g as g$1,a as a$2,h,j,k}from'./chunk-QN73CYII.js';export{a as getConfig}from'./chunk-QN73CYII.js';import ze from'dotenv';import nt from'http';import q from'express';import y,{z as z$1}from'zod';import {ObjectId,MongoClient}from'mongodb';export{ObjectId}from'mongodb';import {randomBytes}from'crypto';import st from'os';import lt from'bcrypt';import {createServer,defineConfig}from'vite';import wt from'@vitejs/plugin-react';import L from'path';import bt from'fs';function Fe(){return typeof window!="object"}function w(){if(!Fe())throw new Error("This function can only be called on the server")}var oe=new Map,C={authenticated:null,unauthenticated:null};function ne(t,e){C.authenticated=e.authenticated,C.unauthenticated=e.unauthenticated;for(let[o,n]of Object.entries(t))oe.set(o,n);}function v(){return C.unauthenticated?[C.unauthenticated]:[]}function re(){return C.authenticated?[C.authenticated]:[]}function ie(t,e){let o=e.find(n=>!Le(t,n));if(o)throw new Error(`Access denied - missing permission: '${o}'`)}function Le(t,e){for(let o of t){let n=oe.get(o);if(n&&n.permissions.includes(e))return true}return false}var N={};function U(t,e){return w(),le(t),I("query",t,e)}function se(t,e){return w(),le(t),I("mutation",t,e)}function ae(t,e){return w(),de(t),I("query",t,e)}function ce(t,e){return w(),de(t),I("mutation",t,e)}function le(t){if(t.toLowerCase().startsWith("_system."))throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${t})`)}function de(t){if(!t.toLowerCase().startsWith("_system."))throw new Error(`System method name must start with a prefix: '_system.' (${t})`)}function I(t,e,o){if(w(),N[e])throw new Error(`Method with name '${e}' is already defined.`);let n=typeof o=="function"?o:o.handler,i=typeof o=="function"?[]:o.permissions??[];N[e]={type:t,name:e,handler:n,permissions:i};}async function ue(t,e,o){w();let n=N[t];if(!n)throw new Error(`Method with name '${t}' is not defined.`);let{type:i,handler:r}=n,s=j("method",`method:${t}`,{type:i,args:e}),c;try{ie(o.roles,n.permissions),c=await r(e,o);}catch(h){throw s.end("error"),h}return s.end(),c}var p=class{constructor(e,{stores:o=[],queries:n={},mutations:i={},routes:r=[],cronJobs:s={},configSchema:c={}}){this.name=e,this.stores=o,this.queries=n,this.mutations=i,this.routes=r,this.cronJobs=s,this.configSchema=c;}};var f=class{constructor(e,o){this.name=e,this.schema=o.schema,this.methods=o.methods,this.indexes=o.indexes;}getName(){return this.name}getSchema(){return this.schema}init(e){if(this.collection)throw new Error(`Collection ${this.name} is already initialized`);this.client=e,this.collection=this.client.db().collection(this.name);}async createIndexes(){this.indexes.length>0&&await this.requireCollection().createIndexes(this.indexes);}wrapDocument(e){return this.methods?Object.create(null,Object.getOwnPropertyDescriptors({...e,...this.methods})):e}requireCollection(){if(!this.collection)throw new Error(`Collection ${this.name} is not provisioned`);return this.collection}requireClient(){if(!this.client)throw new Error("Database is not connected");return this.client}async findOne(e,o){let n=await this.requireCollection().findOne(e,o);return n?this.wrapDocument(n):null}async requireOne(e,o,n){let i=await this.findOne(e,o);if(!i)throw n?n():new Error(`Record not found in ${this.name}`);return i}find(e,o){let n=this.requireCollection().find(e);return o?.sort&&n.sort(o.sort),o?.limit&&n.limit(o.limit),o?.skip&&n.skip(o.skip),n}async findById(e){let o=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(o)}async requireById(e,o){let n=await this.findById(e);if(!n)throw o?o():new Error(`Record with id ${e} not found in ${this.name}`);return n}async fetch(e,o){return (await this.find(e,o).toArray()).map(this.wrapDocument.bind(this))}async insertOne(e){return await this.requireCollection().insertOne(e)}async insertMany(e){return await this.requireCollection().insertMany(e)}async updateOne(e,o){let n=typeof e=="string"?{_id:new ObjectId(e)}:e;return await this.requireCollection().updateOne(n,o)}async upsertOne(e,o){return await this.requireCollection().updateOne(e,o,{upsert:true})}async updateMany(e,o,n){return await this.requireCollection().updateMany(e,o,n)}async upsertMany(e,o){return await this.requireCollection().updateMany(e,o,{upsert:true})}async deleteOne(e){return await this.requireCollection().deleteOne(e)}async deleteMany(e){return await this.requireCollection().deleteMany(e)}aggregate(e,o){return this.requireCollection().aggregate(e,o)}bulkWrite(e){return this.requireCollection().bulkWrite(e)}getDatabase(){return this.requireClient().db()}rawCollection(){return this.requireCollection()}async renameFrom(e,o){let n=this.getDatabase();if(!this.collection||!n)throw new Error(`Store ${this.name} is not provisioned`);if((await n.listCollections({name:e}).toArray()).length===0)throw new Error(`Collection ${e} not found`);if((await n.listCollections({name:this.name}).toArray()).length>0)throw new Error(`Collection ${this.name} already exists`);await n.collection(e).rename(this.name,o);}};var We=z$1.string.bind(z$1),Ke=z$1.number.bind(z$1),Ve=z$1.date.bind(z$1),He=z$1.boolean.bind(z$1),Ze=z$1.array.bind(z$1),Qe=z$1.object.bind(z$1),Ge=z$1.enum.bind(z$1),a={string:We,number:Ke,date:Ve,boolean:He,array:Ze,object:Qe,enum:Ge,objectId(){return z$1.instanceof(ObjectId)},userId(){return z$1.instanceof(ObjectId)},ref(t){return z$1.instanceof(ObjectId)},union:z$1.union.bind(z$1),infer(t){return {}}};var x=new f("_modelenceSessions",{schema:{authToken:a.string(),createdAt:a.date(),expiresAt:a.date(),userId:a.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function pe(t){let e=t?await x.findOne({authToken:t}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await Xe()}async function fe(t,e){await x.updateOne({authToken:t},{$set:{userId:e}});}async function he(t){await x.updateOne({authToken:t},{$set:{userId:null}});}async function Xe(){let t=randomBytes(32).toString("base64url"),e=Date.now(),o=new Date(e+a$1.days(7));return await x.insertOne({authToken:t,createdAt:new Date(e),expiresAt:o,userId:null}),{authToken:t,expiresAt:o,userId:null}}async function et(t){let e=Date.now(),o=new Date(e+a$1.days(7));await x.updateOne({authToken:t.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:o}});}var ge=new p("_system.session",{stores:[x],mutations:{init:async function(t,{session:e,user:o}){return {session:e,user:o,configs:b$1()}},heartbeat:async function(t,{session:e}){e&&await et(e);}}});var u=new f("_modelenceUsers",{schema:{handle:a.string(),emails:a.array(a.object({address:a.string(),verified:a.boolean()})).optional(),createdAt:a.date(),authMethods:a.object({password:a.object({hash:a.string()}).optional(),google:a.object({id:a.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}}]});async function ye(t){let e=await pe(t),o=e.userId?await u.findOne({_id:new ObjectId(e.userId)}):null,n=o?{id:o._id.toString(),handle:o.handle}:null,i=n?re():v();return {user:n,session:e,roles:i}}function we(t){return async(e,o)=>{try{let n=await t({query:e.query,body:e.body,params:e.params,headers:e.headers,cookies:e.cookies,req:e});o.status(n.status||200),n.headers&&Object.entries(n.headers).forEach(([i,r])=>{o.setHeader(i,r);}),o.send(n.data);}catch(n){n instanceof a$4||n instanceof b$2?o.status(n.status).send(n.message):(console.error(`Error in route handler: ${e.path}`),console.error(n),o.status(500).send(String(n)));}}}var g=null;async function be(){if(g)return g;let t=D();if(!t)throw new Error("MongoDB URI is not set");g=new MongoClient(t,{maxPoolSize:20});try{return await g.connect(),await g.db("admin").command({ping:1}),console.log("Pinged your deployment. You successfully connected to MongoDB!"),g}catch(e){throw console.error(e),g=null,e}}function D(){let t=a$2("_system.mongodbUri");return t?String(t):void 0}function Ce(){return g}function rt(t,e){for(let o of e)for(let n of o.routes){let{path:i,handlers:r}=n;Object.entries(r).forEach(([s,c])=>{t[s](i,we(c));});}}async function xe(t,{combinedModules:e}){let o=q();o.use(q.json()),o.use(q.urlencoded({extended:true})),o.post("/api/_internal/method/:methodName(*)",async(r,s)=>{let{methodName:c}=r.params,h=await it(r);try{let d=await ue(c,r.body.args,h);s.json({data:d,typeMap:a$3(d)});}catch(d){if(console.error(`Error in method ${c}:`,d),d instanceof Error&&d?.constructor?.name==="ZodError"&&"errors"in d){let S=d.flatten(),E=Object.entries(S.fieldErrors).map(([j,P])=>`${j}: ${(P??[]).join(", ")}`).join("; "),A=S.formErrors.join("; "),k=[E,A].filter(Boolean).join("; ");s.status(400).send(k);}else s.status(500).send(d instanceof Error?d.message:String(d));}}),rt(o,e),await t.init(),t.middlewares&&o.use(t.middlewares()),o.all("*",(r,s)=>t.handler(r,s)),process.on("unhandledRejection",(r,s)=>{console.error("Unhandled Promise Rejection:"),console.error(r instanceof Error?r.stack:r),console.error("Promise:",s);}),process.on("uncaughtException",r=>{console.error("Uncaught Exception:"),console.error(r.stack),console.trace("Full application stack:");});let n=nt.createServer(o),i=process.env.PORT||3e3;n.listen(i,()=>{h("Application started",{source:"app"}),console.log(`Application started on port ${i}`);});}async function it(t){let e=y.string().nullish().transform(r=>r??null).parse(t.body.authToken),o=y.object({screenWidth:y.number(),screenHeight:y.number(),windowWidth:y.number(),windowHeight:y.number(),pixelRatio:y.number(),orientation:y.string().nullable()}).parse(t.body.clientInfo),n={ip:t.ip||t.socket.remoteAddress,userAgent:t.get("user-agent"),acceptLanguage:t.get("accept-language"),referrer:t.get("referrer")};if(!!D()){let{session:r,user:s,roles:c}=await ye(e);return {clientInfo:o,connectionInfo:n,session:r,user:s,roles:c}}return {clientInfo:o,connectionInfo:n,session:null,user:null,roles:v()}}async function Se({configSchema:t,cronJobsMetadata:e,stores:o}){let n=process.env.MODELENCE_CONTAINER_ID;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set");try{let i=Object.values(o).map(s=>({name:s.getName(),schema:s.getSchema(),collections:[s.getName()]})),r=await B("/api/connect","POST",{hostname:st.hostname(),containerId:n,dataModels:i,configSchema:t,cronJobsMetadata:e});if(r.status==="error")throw new Error(r.error);return console.log("Successfully connected to Modelence Cloud"),r}catch(i){throw console.error("Unable to connect to Modelence Cloud:",i),i}}async function Ee(){return await B("/api/configs","GET")}async function Me(){return await B("/api/sync","POST",{containerId:process.env.MODELENCE_CONTAINER_ID})}async function B(t,e,o){let{MODELENCE_SERVICE_ENDPOINT:n,MODELENCE_SERVICE_TOKEN:i}=process.env;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set");let r=await fetch(`${n}${t}`,{method:e,headers:{Authorization:`Bearer ${i}`,...o?{"Content-Type":"application/json"}:{}},body:o?JSON.stringify(o):void 0});if(!r.ok){let s=await r.text();try{let c=JSON.parse(s);throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${r.status}, ${c?.error}`)}catch{throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${r.status}, ${s}`)}}return await r.json()}var z=false,at=a$1.seconds(10);function De(){setInterval(async()=>{if(!z){z=true;try{await Me();}catch(t){console.error("Error syncing status",t);}try{await ct();}catch(t){console.error("Error syncing config",t);}z=false;}},at);}async function ct(){let{configs:t}=await Ee();c(t);}async function Te(t,{user:e}){let o=z$1.string().email().parse(t.email),n=z$1.string().min(8,{message:"Password must contain at least 8 characters"}).parse(t.password),i=await u.findOne({"emails.address":o},{collation:{locale:"en",strength:2}});if(i){let c=i.emails?.find(h=>h.address===o);throw new Error(`User with email already exists: ${c?.address}`)}let r=await lt.hash(n,10);return (await u.insertOne({handle:o,emails:[{address:o,verified:false}],createdAt:new Date,authMethods:{password:{hash:r}}})).insertedId}async function Ie(t,{user:e,session:o}){if(!o)throw new Error("Session is not initialized");let n=z$1.string().email().parse(t.email),i=z$1.string().parse(t.password),r=await u.findOne({"emails.address":n},{collation:{locale:"en",strength:2}}),s=r?.authMethods?.password?.hash;if(!r||!s||!await lt.compare(i,s))throw ve();return await fe(o.authToken,r._id),{user:{id:r._id,handle:r.handle}}}async function _e(t,{user:e,session:o}){if(!o)throw new Error("Session is not initialized");await he(o.authToken);}function ve(){return new Error("Incorrect email/password combination")}async function Ae(t,{user:e}){if(!e)throw new Error("Not authenticated");let o=await u.requireById(e.id);return {handle:o.handle,emails:o.emails,authMethods:Object.keys(o.authMethods||{})}}var ke=new p("_system.user",{stores:[u],queries:{getOwnProfile:Ae},mutations:{signupWithPassword:Te,loginWithPassword:Ie,logout:_e}});var _=new f("_modelenceMigrations",{schema:{version:a.number(),appliedAt:a.date()},indexes:[{key:{version:1},unique:true}]});async function je(t){if(t.length===0)return;let e=t.map(({version:r})=>r),o=await _.fetch({version:{$in:e}}),n=new Set(o.map(({version:r})=>r)),i=t.filter(({version:r})=>!n.has(r));if(i.length!==0){console.log(`Running migrations (${i.length})...`);for(let{version:r,description:s,handler:c}of i)console.log(`Running migration v${r}: ${s}`),await _.insertOne({version:r,appliedAt:new Date}),await c(),console.log(`Migration v${r} complete`);}}var Pe=new p("_system.migration",{stores:[_]});var ut=a$1.minutes(1),mt=a$1.seconds(10),b={},F,R=new f("_modelenceCronJobs",{schema:{alias:a.string(),lastStartDate:a.date().optional(),lock:a.object({containerId:a.string(),acquireDate:a.date()}).optional()},indexes:[{key:{alias:1},unique:true,background:true}]});function Ne(t,{description:e="",interval:o,timeout:n=ut,handler:i}){if(b[t])throw new Error(`Duplicate cron job declaration: '${t}' already exists`);if(F)throw new Error(`Unable to add a cron job - cron jobs have already been initialized: [${t}]`);if(o<a$1.seconds(5))throw new Error(`Cron job interval should not be less than 5 second [${t}]`);if(n>a$1.days(1))throw new Error(`Cron job timeout should not be longer than 1 day [${t}]`);b[t]={alias:t,params:{description:e,interval:o,timeout:n},handler:i,state:{isRunning:false}};}async function Ue(){if(F)throw new Error("Cron jobs already started");let t=Object.keys(b);if(t.length>0){let e={alias:{$in:t}},o=await R.findOne({...e,"lock.containerId":{$exists:true}});await R.upsertMany(e,{$set:{lock:{containerId:process.env.MODELENCE_CONTAINER_ID||"unknown",acquireDate:new Date}}}),o&&await pt(mt);let n=await R.fetch(e),i=Date.now();n.forEach(r=>{let s=b[r.alias];s&&(s.state.scheduledRunTs=r.lastStartDate?r.lastStartDate.getTime()+s.params.interval:i);}),Object.values(b).forEach(r=>{r.state.scheduledRunTs||(r.state.scheduledRunTs=i);}),F=setInterval(ft,a$1.seconds(1));}}function pt(t){return new Promise(e=>setTimeout(e,t))}async function ft(){let t=Date.now();Object.values(b).forEach(async e=>{let{params:o,state:n}=e;if(n.isRunning){n.startTs&&n.startTs+o.timeout<t&&(n.isRunning=false);return}n.scheduledRunTs&&n.scheduledRunTs<=t&&await ht(e);});}async function ht(t){let{alias:e,params:o,handler:n,state:i}=t;i.isRunning=true,i.startTs=Date.now();let r=j("cron",`cron:${e}`);n().then(()=>{$e(i,o),r.end("success");}).catch(s=>{$e(i,o),k(s),r.end("error"),console.error(`Error in cron job '${e}':`,s);}),await R.updateOne({alias:e},{$set:{lastStartDate:new Date(i.startTs)}});}function $e(t,e){t.scheduledRunTs=t.startTs?t.startTs+e.interval:Date.now(),t.startTs=void 0,t.isRunning=false;}function Je(){return Object.values(b).map(({alias:t,params:e})=>({alias:t,description:e.description,interval:e.interval,timeout:e.timeout}))}var qe=new p("_system.cron",{stores:[R]});var W=class{async init(){this.isDev()&&(console.log("Starting Vite dev server..."),this.viteServer=await createServer({...defineConfig(await xt()),server:{middlewareMode:true},root:"./src/client"}));}middlewares(){return this.isDev()?this.viteServer?.middlewares??[]:[q.static("./.modelence/build/client")]}handler(e,o){if(this.isDev())try{o.sendFile("index.html",{root:"./src/client"});}catch(n){console.error("Error serving index.html:",n),o.status(500).send("Internal Server Error");}else o.sendFile("index.html",{root:"./.modelence/build/client"});}isDev(){return process.env.NODE_ENV!=="production"}};async function xt(){let t=process.cwd(),e=[".eslintrc.js",".eslintrc.json",".eslintrc","eslint.config.js",".eslintrc.yml",".eslintrc.yaml"].find(n=>bt.existsSync(L.join(t,n))),o=[wt(),St()];if(e){let n=(await import('vite-plugin-eslint')).default;o.push(n({failOnError:false,include:["src/**/*.js","src/**/*.jsx","src/**/*.ts","src/**/*.tsx"],cwd:t,overrideConfigFile:L.resolve(t,e)}));}return {plugins:o,root:t,build:{outDir:".modelence/build/client",emptyOutDir:true},server:{proxy:{"/api":"http://localhost:4000"},headers:{"Cache-Control":"no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0",Pragma:"no-cache",Expires:"0"},hmr:{port:0}},resolve:{alias:{"@":L.resolve(t,"src")}}}}function St(){return {name:"modelence-asset-handler",async transform(t,e){if(/\.(png|jpe?g|gif|svg|mpwebm|ogg|mp3|wav|flac|aac)$/.test(e))return process.env.NODE_ENV==="development",t},async generateBundle(t,e){}}}var Be=new W;async function Et({modules:t=[],roles:e$1={},defaultRoles:o={},server:n=Be,migrations:i=[]}){ze.config(),ze.config({path:".modelence.env"});let r=!!process.env.MODELENCE_SERVICE_ENDPOINT,s=process.env.MODELENCE_CRON_ENABLED==="true";_t().then(()=>{}).catch(()=>{});let c$1=[ke,ge,qe,Pe],h=[...c$1,...t];e(),Dt(c$1),Mt(t),ne(e$1,o);let d$1=Tt(h);d(d$1??{});let T=Rt(h);if(s&&Ot(h),r){let{configs:E,environmentId:A,appAlias:k,environmentAlias:j,telemetry:P}=await Se({configSchema:d$1,cronJobsMetadata:s?Je():void 0,stores:T});c(E),f$1({environmentId:A,appAlias:k,environmentAlias:j,telemetry:P});}else c(It());let S=D();if(S&&(await be(),vt(T)),s&&await je(i),S)for(let E of T)E.createIndexes();r&&(await g$1(),De()),s&&Ue().catch(console.error),await xe(n,{combinedModules:h});}function Mt(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))U(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))se(`${e.name}.${o}`,n);}}function Dt(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))ae(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))ce(`${e.name}.${o}`,n);}}function Rt(t){return t.flatMap(e=>e.stores)}function Tt(t){let e={};for(let o of t)for(let[n,i]of Object.entries(o.configSchema)){let r=`${o.name}.${n}`;if(r in e)throw new Error(`Duplicate config schema key: ${r} (${o.name})`);e[r]=i;}return e}function Ot(t){for(let e of t)for(let[o,n]of Object.entries(e.cronJobs))Ne(`${e.name}.${o}`,n);}function vt(t){let e=Ce();if(!e)throw new Error("Failed to initialize stores: MongoDB client not initialized");for(let o of t)o.init(e);}function It(){let t=[];return process.env.MONGODB_URI&&t.push({key:"_system.mongodbUri",type:"string",value:process.env.MONGODB_URI}),t}async function _t(){if(process.env.MODELENCE_TRACKING_ENABLED!=="false"){let e=process.env.MODELENCE_SERVICE_ENDPOINT??"https://cloud.modelence.com",o=await import('./package-OWDOQ74X.js');await fetch(`${e}/api/track/app-start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({version:o.default.version})});}}
2
2
  export{p as Module,f as Store,U as createQuery,u as dbUsers,a as schema,Et as startApp};//# sourceMappingURL=server.js.map
3
3
  //# sourceMappingURL=server.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "modelence",
4
- "version": "0.5.1-dev.4",
4
+ "version": "0.5.1",
5
5
  "description": "The Node.js Framework for Real-Time MongoDB Apps",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/global.d.ts",
@@ -1,3 +0,0 @@
1
- var s="module",i="modelence",n="0.5.1-dev.4",o="The Node.js Framework for Real-Time MongoDB Apps",p="dist/index.js",r="dist/global.d.ts",d={".":"./dist/index.js","./client":"./dist/client.js","./server":"./dist/server.js","./telemetry":"./dist/telemetry.js","./mongodb":"./dist/mongo.js"},c=["dist","dist/bin"],l={modelence:"./dist/bin/modelence.js"},m={build:"tsup",dev:"tsup --watch",prepublishOnly:"npm run build",test:'echo "Error: no test specified" && exit 1',postversion:"git push && git push --tags"},a={type:"git",url:"git+https://github.com/modelence/modelence.git"},u="Modelence",y="SEE LICENSE IN LICENSE",g={url:"https://github.com/modelence/modelence/issues"},h="https://modelence.com",b={"@types/archiver":"^6.0.3","@types/bcrypt":"^5.0.2","@types/express":"^5.0.0","@types/fs-extra":"^11.0.4","@types/node":"^22.5.1","@types/react":"^19.0.0","@types/react-dom":"^19.0.1","@typescript-eslint/eslint-plugin":"^8.17.0","@typescript-eslint/parser":"^8.17.0",react:"^19.0.0","react-dom":"^19.0.0",typescript:"^5.7.2"},v={"@octokit/rest":"^20.0.2","@vitejs/plugin-react":"^4.3.4",archiver:"^7.0.1",bcrypt:"^5.1.1",commander:"^12.0.0",dotenv:"^16.4.5","elastic-apm-node":"^4.8.0",express:"^4.21.0","fs-extra":"^11.2.0",jiti:"^2.4.2",mongodb:"^6.8.1",open:"^10.1.0",tsup:"^8.3.6",tsx:"^4.19.3",vite:"^6.0.3","vite-plugin-eslint":"^1.8.1",winston:"^3.15.0","winston-elasticsearch":"^0.19.0",zod:"^3.23.8",zustand:"^5.0.2"},j={react:">=18.0.0","react-dom":">=18.0.0"},x={type:s,name:i,version:n,description:o,main:p,types:r,exports:d,files:c,bin:l,scripts:m,repository:a,author:u,license:y,bugs:g,homepage:h,devDependencies:b,dependencies:v,peerDependencies:j};
2
- export{u as author,l as bin,g as bugs,x as default,v as dependencies,o as description,b as devDependencies,d as exports,c as files,h as homepage,y as license,p as main,i as name,j as peerDependencies,a as repository,m as scripts,s as type,r as types,n as version};//# sourceMappingURL=package-WATZNRLZ.js.map
3
- //# sourceMappingURL=package-WATZNRLZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../package.json"],"names":["type","name","version","description","main","types","exports","files","bin","scripts","repository","author","license","bugs","homepage","devDependencies","dependencies","peerDependencies","package_default"],"mappings":"AACE,IAAAA,EAAQ,QACRC,CAAAA,CAAAA,CAAQ,YACRC,CAAW,CAAA,aAAA,CACXC,EAAe,kDACfC,CAAAA,CAAAA,CAAQ,gBACRC,CAAS,CAAA,kBAAA,CACTC,EAAW,CACT,GAAA,CAAK,kBACL,UAAY,CAAA,kBAAA,CACZ,WAAY,kBACZ,CAAA,aAAA,CAAe,qBACf,CAAA,WAAA,CAAa,iBACf,CACAC,CAAAA,CAAAA,CAAS,CACP,MACA,CAAA,UACF,EACAC,CAAO,CAAA,CACL,UAAa,yBACf,CAAA,CACAC,EAAW,CACT,KAAA,CAAS,OACT,GAAO,CAAA,cAAA,CACP,eAAkB,eAClB,CAAA,IAAA,CAAQ,2CACR,CAAA,WAAA,CAAe,6BACjB,CACAC,CAAAA,CAAAA,CAAc,CACZ,IAAQ,CAAA,KAAA,CACR,IAAO,gDACT,CAAA,CACAC,EAAU,WACVC,CAAAA,CAAAA,CAAW,yBACXC,CAAQ,CAAA,CACN,IAAO,+CACT,CAAA,CACAC,EAAY,uBACZC,CAAAA,CAAAA,CAAmB,CACjB,iBAAA,CAAmB,SACnB,eAAiB,CAAA,QAAA,CACjB,iBAAkB,QAClB,CAAA,iBAAA,CAAmB,UACnB,aAAe,CAAA,SAAA,CACf,eAAgB,SAChB,CAAA,kBAAA,CAAoB,UACpB,kCAAoC,CAAA,SAAA,CACpC,4BAA6B,SAC7B,CAAA,KAAA,CAAS,UACT,WAAa,CAAA,SAAA,CACb,UAAc,CAAA,QAChB,EACAC,CAAgB,CAAA,CACd,gBAAiB,SACjB,CAAA,sBAAA,CAAwB,SACxB,QAAY,CAAA,QAAA,CACZ,OAAU,QACV,CAAA,SAAA,CAAa,UACb,MAAU,CAAA,SAAA,CACV,mBAAoB,QACpB,CAAA,OAAA,CAAW,UACX,UAAY,CAAA,SAAA,CACZ,IAAQ,CAAA,QAAA,CACR,QAAW,QACX,CAAA,IAAA,CAAQ,UACR,IAAQ,CAAA,QAAA,CACR,IAAO,SACP,CAAA,IAAA,CAAQ,SACR,oBAAsB,CAAA,QAAA,CACtB,QAAW,SACX,CAAA,uBAAA,CAAyB,UACzB,GAAO,CAAA,SAAA,CACP,QAAW,QACb,CAAA,CACAC,CAAoB,CAAA,CAClB,MAAS,UACT,CAAA,WAAA,CAAa,UACf,CA7EFC,CAAAA,CAAAA,CAAA,CACE,IAAAlB,CAAAA,CAAAA,CACA,KAAAC,CACA,CAAA,OAAA,CAAAC,EACA,WAAAC,CAAAA,CAAAA,CACA,KAAAC,CACA,CAAA,KAAA,CAAAC,EACA,OAAAC,CAAAA,CAAAA,CAOA,KAAAC,CAAAA,CAAAA,CAIA,IAAAC,CAGA,CAAA,OAAA,CAAAC,EAOA,UAAAC,CAAAA,CAAAA,CAIA,OAAAC,CACA,CAAA,OAAA,CAAAC,EACA,IAAAC,CAAAA,CAAAA,CAGA,SAAAC,CACA,CAAA,eAAA,CAAAC,EAcA,YAAAC,CAAAA,CAAAA,CAsBA,iBAAAC,CAIF","file":"package-WATZNRLZ.js","sourcesContent":["{\n \"type\": \"module\",\n \"name\": \"modelence\",\n \"version\": \"0.5.1-dev.4\",\n \"description\": \"The Node.js Framework for Real-Time MongoDB Apps\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/global.d.ts\",\n \"exports\": {\n \".\": \"./dist/index.js\",\n \"./client\": \"./dist/client.js\",\n \"./server\": \"./dist/server.js\",\n \"./telemetry\": \"./dist/telemetry.js\",\n \"./mongodb\": \"./dist/mongo.js\"\n },\n \"files\": [\n \"dist\",\n \"dist/bin\"\n ],\n \"bin\": {\n \"modelence\": \"./dist/bin/modelence.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n \"postversion\": \"git push && git push --tags\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/modelence/modelence.git\"\n },\n \"author\": \"Modelence\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"bugs\": {\n \"url\": \"https://github.com/modelence/modelence/issues\"\n },\n \"homepage\": \"https://modelence.com\",\n \"devDependencies\": {\n \"@types/archiver\": \"^6.0.3\",\n \"@types/bcrypt\": \"^5.0.2\",\n \"@types/express\": \"^5.0.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/node\": \"^22.5.1\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.1\",\n \"@typescript-eslint/eslint-plugin\": \"^8.17.0\",\n \"@typescript-eslint/parser\": \"^8.17.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\",\n \"typescript\": \"^5.7.2\"\n },\n \"dependencies\": {\n \"@octokit/rest\": \"^20.0.2\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"archiver\": \"^7.0.1\",\n \"bcrypt\": \"^5.1.1\",\n \"commander\": \"^12.0.0\",\n \"dotenv\": \"^16.4.5\",\n \"elastic-apm-node\": \"^4.8.0\",\n \"express\": \"^4.21.0\",\n \"fs-extra\": \"^11.2.0\",\n \"jiti\": \"^2.4.2\",\n \"mongodb\": \"^6.8.1\",\n \"open\": \"^10.1.0\",\n \"tsup\": \"^8.3.6\",\n \"tsx\": \"^4.19.3\",\n \"vite\": \"^6.0.3\",\n \"vite-plugin-eslint\": \"^1.8.1\",\n \"winston\": \"^3.15.0\",\n \"winston-elasticsearch\": \"^0.19.0\",\n \"zod\": \"^3.23.8\",\n \"zustand\": \"^5.0.2\"\n },\n \"peerDependencies\": {\n \"react\": \">=18.0.0\",\n \"react-dom\": \">=18.0.0\"\n }\n}\n"]}