modelence 0.10.10-dev.0 → 0.10.10-dev.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.
package/dist/server.js CHANGED
@@ -1,19 +1,19 @@
1
- import {a as a$2}from'./chunk-3S2FFBNS.js';import {d as d$1,a as a$3}from'./chunk-C3UESBRX.js';import {a}from'./chunk-DO5TZLF5.js';import {b as b$1,e,d as d$2,c,f,g,j as j$1,a as a$1,i,k as k$1,h as h$1,l}from'./chunk-PB6WQQ4L.js';export{a as getConfig}from'./chunk-PB6WQQ4L.js';import {s}from'./chunk-KEWFK2QA.js';import Qt from'dotenv';import wr from'fs/promises';import Po from'os';import Re from'path';import {Server}from'socket.io';import {createAdapter}from'@socket.io/mongo-adapter';import {MongoError,ObjectId,MongoClient}from'mongodb';export{ObjectId}from'mongodb';import {randomBytes,randomUUID}from'crypto';import R,{z as z$1}from'zod';import To from'bcrypt';import {createServer,defineConfig,loadConfigFromFile,mergeConfig}from'vite';import Go from'@vitejs/plugin-react';import Qo from'fs';import M,{Router}from'express';import pr from'cookie-parser';import mr from'http';var E=class{constructor(e,{stores:o=[],queries:r={},mutations:n={},routes:i=[],cronJobs:s={},configSchema:a={},rateLimits:c=[],channels:l=[]}){this.name=e,this.stores=o,this.queries=r,this.mutations=n,this.routes=i,this.cronJobs=s,this.configSchema=a,this.rateLimits=c,this.channels=l;}};function D(t){let e=t._def;if(e.typeName==="ZodString")return {type:"string"};if(e.typeName==="ZodNumber")return {type:"number"};if(e.typeName==="ZodBoolean")return {type:"boolean"};if(e.typeName==="ZodDate")return {type:"date"};if(e.typeName==="ZodArray")return {type:"array",items:D(e.type)};if(e.typeName==="ZodObject"){let r=e.shape(),n={};for(let[i,s]of Object.entries(r))n[i]=D(s);return {type:"object",items:n}}if(e.typeName==="ZodOptional")return {...D(e.innerType),optional:true};if(e.typeName==="ZodNullable")return {...D(e.innerType),optional:true};if(e.typeName==="ZodEnum")return {type:"enum",items:e.values};if(e.typeName==="ZodUnion")return {type:"union",items:e.options.map(D)};if(e.typeName==="ZodEffects"){let o=e;return o.description?{type:"custom",typeName:o.description}:D(o.schema)}return {type:"custom",typeName:e.typeName}}function te(t){let e={};for(let[o,r]of Object.entries(t))Array.isArray(r)?e[o]=r.map(n=>typeof n=="object"&&"_def"in n?D(n):te(n)):typeof r=="object"&&"_def"in r?e[o]=D(r):e[o]=te(r);return e}var w=class t{constructor(e,o){this.name=e,this.schema=o.schema,this.methods=o.methods,this.indexes=o.indexes,this.searchIndexes=o.searchIndexes||[];}getName(){return this.name}getSchema(){return this.schema}getSerializedSchema(){return te(this.schema)}extend(e){let o={...this.schema,...e.schema||{}},r=[...this.indexes,...e.indexes||[]],n=[...this.searchIndexes,...e.searchIndexes||[]],i={...this.methods||{},...e.methods||{}},s=new t(this.name,{schema:o,methods:i,indexes:r,searchIndexes:n});if(this.client)throw new Error(`Store.extend() must be called before startApp(). Store '${this.name}' has already been initialized and cannot be extended.`);return s}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(){if(this.indexes.length>0)for(let e of this.indexes)try{await this.requireCollection().createIndexes([e]);}catch(o){if(o instanceof MongoError&&o.code===86&&e.name)await this.requireCollection().dropIndex(e.name),await this.requireCollection().createIndexes([e]);else throw o}if(this.searchIndexes.length>0)for(let e of this.searchIndexes)try{await this.requireCollection().createSearchIndexes([e]);}catch(o){if(o instanceof MongoError&&o.code===68&&e.name)await this.requireCollection().dropSearchIndex(e.name),await this.requireCollection().createSearchIndexes([e]);else throw o}}wrapDocument(e){return this.methods?Object.create(null,Object.getOwnPropertyDescriptors({...e,...this.methods})):e}getSelector(e){return typeof e=="string"?{_id:new ObjectId(e)}:e instanceof ObjectId?{_id:e}: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 r=await this.requireCollection().findOne(e,o);return r?this.wrapDocument(r):null}async requireOne(e,o,r){let n=await this.findOne(e,o);if(!n)throw r?r():new Error(`Record not found in ${this.name}`);return n}find(e,o){let r=this.requireCollection().find(e);return o?.sort&&r.sort(o.sort),o?.limit&&r.limit(o.limit),o?.skip&&r.skip(o.skip),r}async findById(e){let o=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(o)}async requireById(e,o){let r=await this.findById(e);if(!r)throw o?o():new Error(`Record with id ${e} not found in ${this.name}`);return r}countDocuments(e){return this.requireCollection().countDocuments(e)}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){return await this.requireCollection().updateOne(this.getSelector(e),o)}async upsertOne(e,o){return await this.requireCollection().updateOne(this.getSelector(e),o,{upsert:true})}async updateMany(e,o,r){return await this.requireCollection().updateMany(e,o,r)}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 r=this.getDatabase();if(!this.collection||!r)throw new Error(`Store ${this.name} is not provisioned`);if((await r.listCollections({name:e}).toArray()).length===0)throw new Error(`Collection ${e} not found`);if((await r.listCollections({name:this.name}).toArray()).length>0)throw new Error(`Collection ${this.name} already exists`);await r.collection(e).rename(this.name,o);}async vectorSearch({field:e,embedding:o,numCandidates:r,limit:n,projection:i,indexName:s}){return this.aggregate([{$vectorSearch:{index:s||e+"VectorSearch",path:e,queryVector:o,numCandidates:r||100,limit:n||10}},{$project:{_id:1,score:{$meta:"vectorSearchScore"},...i}}])}static vectorIndex({field:e,dimensions:o,similarity:r="cosine",indexName:n}){return {type:"vectorSearch",name:n||e+"VectorSearch",definition:{fields:[{type:"vector",path:e,numDimensions:o,similarity:r}]}}}};var to=z$1.string.bind(z$1),oo=z$1.number.bind(z$1),ro=z$1.date.bind(z$1),no=z$1.boolean.bind(z$1),io=z$1.array.bind(z$1),so=z$1.object.bind(z$1),ao=z$1.enum.bind(z$1),d={string:to,number:oo,date:ro,boolean:no,array:io,object:so,enum:ao,embedding(){return z$1.array(z$1.number())},objectId(){return z$1.instanceof(ObjectId).describe("ObjectId")},userId(){return z$1.instanceof(ObjectId).describe("UserId")},ref(t){return z$1.instanceof(ObjectId).describe("Ref")},union:z$1.union.bind(z$1),infer(t){return {}}};var N=new w("_modelenceSessions",{schema:{authToken:d.string(),createdAt:d.date(),expiresAt:d.date(),userId:d.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function Je(t){let e=t?await N.findOne({authToken:t}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await ge()}async function Ge(t,e){await N.updateOne({authToken:t},{$set:{userId:e}});}async function Qe(t){await N.updateOne({authToken:t},{$set:{userId:null}});}async function ge(t=null){let e=randomBytes(32).toString("base64url"),o=Date.now(),r=new Date(o+a.days(7));return await N.insertOne({authToken:e,createdAt:new Date(o),expiresAt:r,userId:t}),{authToken:e,expiresAt:r,userId:t}}async function lo(t){let e=Date.now(),o=new Date(e+a.days(7));await N.updateOne({authToken:t.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:o}});}var He=new E("_system.session",{stores:[N],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 lo(e);}}});var p=new w("_modelenceUsers",{schema:{handle:d.string(),emails:d.array(d.object({address:d.string(),verified:d.boolean()})).optional(),status:d.enum(["active","disabled","deleted"]).optional(),createdAt:d.date(),disabledAt:d.date().optional(),deletedAt:d.date().optional(),roles:d.array(d.string()).optional(),authMethods:d.object({password:d.object({hash:d.string()}).optional(),google:d.object({id:d.string()}).optional(),github:d.object({id:d.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}},{key:{"emails.address":1,status:1}},{key:{"authMethods.google.id":1,status:1},sparse:true},{key:{"authMethods.github.id":1,status:1},sparse:true}]}),J=new w("_modelenceDisposableEmailDomains",{schema:{domain:d.string(),addedAt:d.date()},indexes:[{key:{domain:1},unique:true}]}),_=new w("_modelenceEmailVerificationTokens",{schema:{userId:d.objectId(),email:d.string().optional(),token:d.string(),createdAt:d.date(),expiresAt:d.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]}),v=new w("_modelenceResetPasswordTokens",{schema:{userId:d.objectId(),token:d.string(),createdAt:d.date(),expiresAt:d.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var Ke=new Map,z={authenticated:null,unauthenticated:null};function Ye(t,e){z.authenticated=e.authenticated,z.unauthenticated=e.unauthenticated;for(let[o,r]of Object.entries(t))Ke.set(o,r);}function oe(){return z.unauthenticated?[z.unauthenticated]:[]}function Xe(){return z.authenticated?[z.authenticated]:[]}function ye(t,e){let o=e.find(r=>!uo(t,r));if(o)throw new Error(`Access denied - missing permission: '${o}'`)}function uo(t,e){for(let o of t){let r=Ke.get(o);if(r&&r.permissions.includes(e))return true}return false}async function k(t){let e=await Je(t),o=e.userId?await p.findOne({_id:new ObjectId(e.userId),status:{$nin:["deleted","disabled"]}}):null,r=o?{id:o._id.toString(),handle:o.handle,roles:o.roles||[],hasRole:i=>(o.roles||[]).includes(i),requireRole:i=>{if(!(o.roles||[]).includes(i))throw new Error(`Access denied - role '${i}' required`)}}:null,n=r?Xe():oe();return {user:r,session:e,roles:n}}var A=null;async function et(){if(A)return A;let t=P();if(!t)throw new Error("MongoDB URI is not set");A=new MongoClient(t,{maxPoolSize:20,driverInfo:{name:"Modelence",version:s.version},ignoreUndefined:true});try{return await A.connect(),await A.db("admin").command({ping:1}),console.log("Pinged your deployment. You successfully connected to MongoDB!"),A}catch(e){throw console.error(e),A=null,e}}function P(){let t=a$1("_system.mongodbUri");return t?String(t):void 0}function re(){return A}var F=class{constructor(e){this.fetch=e.fetch,this.watch=e.watch;}};function fo(){return typeof window!="object"}function O(){if(!fo())throw new Error("This function can only be called on the server")}function ne(t){return t.replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim()}var ie={};function we(t,e){return O(),nt(t),se("query",t,e)}function tt(t,e){return O(),nt(t),se("mutation",t,e)}function ot(t,e){return O(),it(t),se("query",t,e)}function rt(t,e){return O(),it(t),se("mutation",t,e)}function nt(t){if(t.toLowerCase().startsWith("_system."))throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${t})`)}function it(t){if(!t.toLowerCase().startsWith("_system."))throw new Error(`System method name must start with a prefix: '_system.' (${t})`)}function se(t,e,o){if(O(),ie[e])throw new Error(`Method with name '${e}' is already defined.`);let r=typeof o=="function"?o:o.handler,n=typeof o=="function"?[]:o.permissions??[];ie[e]={type:t,name:e,handler:r,permissions:n};}async function st(t,e,o){O();let r=ie[t];if(!r)throw new Error(`Method with name '${t}' is not defined.`);let{type:n,handler:i}=r,s=k$1("method",`method:${t}`,{type:n,args:e}),a;try{ye(o.roles,r.permissions),a=await i(e,o);}catch(c){throw s.end("error"),c}return s.end(),a}async function at(t,e,o){O();let r=ie[t];if(!r)throw new Error(`Method with name '${t}' is not defined.`);let{type:n,handler:i}=r;if(n!=="query")throw new Error("Live methods are only supported for queries");let s=k$1("method",`method:${t}:live`,{type:n,args:e}),a;try{if(ye(o.roles,r.permissions),a=await i(e,o),!(a instanceof F))throw new Error(`Live query handler for '${t}' must return a LiveData object with fetch and watch functions.`)}catch(c){throw s.end("error"),c}return s.end(),a}var ho=z$1.object({subscriptionId:z$1.string().min(1),method:z$1.string().min(1),args:z$1.record(z$1.unknown()).default({})}),go=z$1.object({subscriptionId:z$1.string().min(1)}),G=new Map;function yo(t){let e=G.get(t.id);return e||(e=new Map,G.set(t.id,e)),e}async function be(t,e){let o=ho.safeParse(e);if(!o.success){t.emit("liveQueryError",{subscriptionId:null,error:`Invalid payload: ${o.error.message}`});return}let{subscriptionId:r,method:n,args:i}=o.data,s=yo(t),a=s.get(r);if(a)if(a.cleanup)try{a.cleanup();}catch(l){console.error("[LiveQuery] Error cleaning up existing subscription:",l);}else a.aborted=true;let c={cleanup:null};s.set(r,c);try{let l=await at(n,i,t.data),f=async()=>{let C=await l.fetch();c.aborted||t.emit("liveQueryData",{subscriptionId:r,data:C,typeMap:a$2(C)});},m=!0,S=!1,x=()=>{c.aborted||!m||S||(m=!1,S=!0,f().catch(C=>{c.aborted||(console.error(`[LiveQuery] Error fetching data for ${n}:`,C),t.emit("liveQueryError",{subscriptionId:r,error:C instanceof Error?C.message:String(C)}));}).finally(()=>{S=!1,x();}));},I=l.watch({publish:()=>{m=!0,x();}});if(c.aborted){if(I)try{I();}catch(C){console.error("[LiveQuery] Error cleaning up after disconnect during setup:",C);}return}c.cleanup=I||null,x();}catch(l){s.delete(r),console.error(`[LiveQuery] Error in ${n}:`,l),t.emit("liveQueryError",{subscriptionId:r,error:l instanceof Error?l.message:String(l)});}}function Ee(t,e){let o=go.safeParse(e);if(!o.success){console.warn(`[LiveQuery] Invalid unsubscribe payload: ${o.error.message}`);return}let{subscriptionId:r}=o.data,n=G.get(t.id);if(!n)return;let i=n.get(r);if(i){if(i.cleanup)try{i.cleanup();}catch(s){console.error("[LiveQuery] Error in cleanup:",s);}else i.aborted=true;n.delete(r);}}function Se(t){let e=G.get(t.id);if(e){for(let o of e.values())if(o.cleanup)try{o.cleanup();}catch(r){console.error("[LiveQuery] Error in cleanup on disconnect:",r);}else o.aborted=true;G.delete(t.id);}}var Q=null,Eo="_modelenceSocketio";async function So({httpServer:t,channels:e}){let o=re();console.log("Initializing Socket.IO server...");let r=null;if(o){r=o.db().collection(Eo);try{await r.createIndex({createdAt:1},{expireAfterSeconds:3600,background:!0});}catch(n){console.error("Failed to create index on MongoDB collection for Socket.IO:",n);}}Q=new Server(t,{cors:{origin:"*",methods:["GET","POST"]},adapter:r?createAdapter(r):void 0,transports:["polling","websocket"],allowUpgrades:true,perMessageDeflate:false}),Q.on("error",n=>{console.error("Socket.IO error:",n);}),Q.use(async(n,i)=>{let s=n.handshake.auth.token;try{n.data=await k(s);}finally{i();}}),Q.on("connection",n=>{console.log("Socket.IO client connected"),n.on("disconnect",()=>{console.log("Socket.IO client disconnected"),Se(n);}),n.on("reauthenticate",async i=>{try{n.data=await k(i),n.emit("reauthenticated",{success:!0});}catch(s){n.emit("reauthenticated",{success:false,error:String(s)});}}),n.on("joinChannel",async i=>{let[s]=i.split(":"),a=false;for(let c of e)if(c.category===s){(!c.canAccessChannel||await c.canAccessChannel(n.data))&&(n.join(i),a=true,n.emit("joinedChannel",i));break}a||n.emit("joinError",{channel:i,error:"Access denied"});}),n.on("leaveChannel",i=>{n.leave(i),console.log(`User ${n.id} left channel ${i}`),n.emit("leftChannel",i);}),n.on("subscribeLiveQuery",i=>be(n,i)),n.on("unsubscribeLiveQuery",i=>Ee(n,i));}),console.log("Socket.IO server initialized");}function Co({category:t,id:e,data:o}){Q?.to(`${t}:${e}`).emit(t,o);}var ct={init:So,broadcast:Co};async function lt(t){let e=t.toLowerCase().trim().split("@");if(e.length!==2)return false;let o=e[1];return !!await J.findOne({domain:o})}var dt={interval:a.days(1),async handler(){let t=await fetch("https://disposable.github.io/disposable-email-domains/domains.txt");if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);let o=(await t.text()).split(`
2
- `).map(i=>i.trim().toLowerCase()).filter(i=>i.length>0),r=new Date,n=500;for(let i=0;i<o.length;i+=n){let s=o.slice(i,i+n);try{await J.insertMany(s.map(a=>({domain:a,addedAt:r})));}catch(a){a&&typeof a=="object"&&"name"in a&&a.name;}}}};var Ce=Object.freeze({});function ut(t){Ce=Object.freeze(Object.assign({},Ce,t));}function b(){return Ce}function pt({name:t,email:e,verificationUrl:o}){return `
1
+ import {a as a$2}from'./chunk-3S2FFBNS.js';import {d as d$1,a as a$3}from'./chunk-C3UESBRX.js';import {a}from'./chunk-DO5TZLF5.js';import {b as b$1,e,d as d$2,c,f as f$1,g,j as j$1,a as a$1,i,k as k$1,h as h$1,l}from'./chunk-PB6WQQ4L.js';export{a as getConfig}from'./chunk-PB6WQQ4L.js';import {s}from'./chunk-XIYDJQT2.js';import Gt from'dotenv';import wr from'fs/promises';import Po from'os';import Me from'path';import {Server}from'socket.io';import {createAdapter}from'@socket.io/mongo-adapter';import {MongoError,ObjectId,MongoClient}from'mongodb';export{ObjectId}from'mongodb';import {randomBytes,randomUUID}from'crypto';import M,{z as z$1}from'zod';import To from'bcrypt';import {createServer,defineConfig,loadConfigFromFile,mergeConfig}from'vite';import Qo from'@vitejs/plugin-react';import Go from'fs';import I,{Router}from'express';import pr from'cookie-parser';import mr from'http';var E=class{constructor(e,{stores:o=[],queries:r={},mutations:n={},routes:i=[],cronJobs:s={},configSchema:a={},rateLimits:c=[],channels:l=[]}){this.name=e,this.stores=o,this.queries=r,this.mutations=n,this.routes=i,this.cronJobs=s,this.configSchema=a,this.rateLimits=c,this.channels=l;}};function k(t){let e=t._def;if(e.typeName==="ZodString")return {type:"string"};if(e.typeName==="ZodNumber")return {type:"number"};if(e.typeName==="ZodBoolean")return {type:"boolean"};if(e.typeName==="ZodDate")return {type:"date"};if(e.typeName==="ZodArray")return {type:"array",items:k(e.type)};if(e.typeName==="ZodObject"){let r=e.shape(),n={};for(let[i,s]of Object.entries(r))n[i]=k(s);return {type:"object",items:n}}if(e.typeName==="ZodOptional")return {...k(e.innerType),optional:true};if(e.typeName==="ZodNullable")return {...k(e.innerType),optional:true};if(e.typeName==="ZodEnum")return {type:"enum",items:e.values};if(e.typeName==="ZodUnion")return {type:"union",items:e.options.map(k)};if(e.typeName==="ZodEffects"){let o=e;return o.description?{type:"custom",typeName:o.description}:k(o.schema)}return {type:"custom",typeName:e.typeName}}function re(t){let e={};for(let[o,r]of Object.entries(t))Array.isArray(r)?e[o]=r.map(n=>typeof n=="object"&&"_def"in n?k(n):re(n)):typeof r=="object"&&"_def"in r?e[o]=k(r):e[o]=re(r);return e}var w=class t{constructor(e,o){this.name=e,this.schema=o.schema,this.methods=o.methods,this.indexes=o.indexes,this.searchIndexes=o.searchIndexes||[];}getName(){return this.name}getSchema(){return this.schema}getSerializedSchema(){return re(this.schema)}extend(e){let o={...this.schema,...e.schema||{}},r=[...this.indexes,...e.indexes||[]],n=[...this.searchIndexes,...e.searchIndexes||[]],i={...this.methods||{},...e.methods||{}},s=new t(this.name,{schema:o,methods:i,indexes:r,searchIndexes:n});if(this.client)throw new Error(`Store.extend() must be called before startApp(). Store '${this.name}' has already been initialized and cannot be extended.`);return s}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(){if(this.indexes.length>0)for(let e of this.indexes)try{await this.requireCollection().createIndexes([e]);}catch(o){if(o instanceof MongoError&&o.code===86&&e.name)await this.requireCollection().dropIndex(e.name),await this.requireCollection().createIndexes([e]);else throw o}if(this.searchIndexes.length>0)for(let e of this.searchIndexes)try{await this.requireCollection().createSearchIndexes([e]);}catch(o){if(o instanceof MongoError&&o.code===68&&e.name)await this.requireCollection().dropSearchIndex(e.name),await this.requireCollection().createSearchIndexes([e]);else throw o}}wrapDocument(e){return this.methods?Object.create(null,Object.getOwnPropertyDescriptors({...e,...this.methods})):e}getSelector(e){return typeof e=="string"?{_id:new ObjectId(e)}:e instanceof ObjectId?{_id:e}: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 r=await this.requireCollection().findOne(e,o);return r?this.wrapDocument(r):null}async requireOne(e,o,r){let n=await this.findOne(e,o);if(!n)throw r?r():new Error(`Record not found in ${this.name}`);return n}find(e,o){let r=this.requireCollection().find(e);return o?.sort&&r.sort(o.sort),o?.limit&&r.limit(o.limit),o?.skip&&r.skip(o.skip),r}async findById(e){let o=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(o)}async requireById(e,o){let r=await this.findById(e);if(!r)throw o?o():new Error(`Record with id ${e} not found in ${this.name}`);return r}countDocuments(e){return this.requireCollection().countDocuments(e)}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){return await this.requireCollection().updateOne(this.getSelector(e),o)}async upsertOne(e,o){return await this.requireCollection().updateOne(this.getSelector(e),o,{upsert:true})}async updateMany(e,o,r){return await this.requireCollection().updateMany(e,o,r)}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 r=this.getDatabase();if(!this.collection||!r)throw new Error(`Store ${this.name} is not provisioned`);if((await r.listCollections({name:e}).toArray()).length===0)throw new Error(`Collection ${e} not found`);if((await r.listCollections({name:this.name}).toArray()).length>0)throw new Error(`Collection ${this.name} already exists`);await r.collection(e).rename(this.name,o);}async vectorSearch({field:e,embedding:o,numCandidates:r,limit:n,projection:i,indexName:s}){return this.aggregate([{$vectorSearch:{index:s||e+"VectorSearch",path:e,queryVector:o,numCandidates:r||100,limit:n||10}},{$project:{_id:1,score:{$meta:"vectorSearchScore"},...i}}])}static vectorIndex({field:e,dimensions:o,similarity:r="cosine",indexName:n}){return {type:"vectorSearch",name:n||e+"VectorSearch",definition:{fields:[{type:"vector",path:e,numDimensions:o,similarity:r}]}}}};var to=z$1.string.bind(z$1),oo=z$1.number.bind(z$1),ro=z$1.date.bind(z$1),no=z$1.boolean.bind(z$1),io=z$1.array.bind(z$1),so=z$1.object.bind(z$1),ao=z$1.enum.bind(z$1),d={string:to,number:oo,date:ro,boolean:no,array:io,object:so,enum:ao,embedding(){return z$1.array(z$1.number())},objectId(){return z$1.instanceof(ObjectId).describe("ObjectId")},userId(){return z$1.instanceof(ObjectId).describe("UserId")},ref(t){return z$1.instanceof(ObjectId).describe("Ref")},union:z$1.union.bind(z$1),infer(t){return {}}};var z=new w("_modelenceSessions",{schema:{authToken:d.string(),createdAt:d.date(),expiresAt:d.date(),userId:d.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function Je(t){let e=t?await z.findOne({authToken:t}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await ye()}async function Qe(t,e){await z.updateOne({authToken:t},{$set:{userId:e}});}async function Ge(t){await z.updateOne({authToken:t},{$set:{userId:null}});}async function ye(t=null){let e=randomBytes(32).toString("base64url"),o=Date.now(),r=new Date(o+a.days(7));return await z.insertOne({authToken:e,createdAt:new Date(o),expiresAt:r,userId:t}),{authToken:e,expiresAt:r,userId:t}}async function lo(t){let e=Date.now(),o=new Date(e+a.days(7));await z.updateOne({authToken:t.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:o}});}var He=new E("_system.session",{stores:[z],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 lo(e);}}});var f=new w("_modelenceUsers",{schema:{handle:d.string(),emails:d.array(d.object({address:d.string(),verified:d.boolean()})).optional(),status:d.enum(["active","disabled","deleted"]).optional(),createdAt:d.date(),disabledAt:d.date().optional(),deletedAt:d.date().optional(),roles:d.array(d.string()).optional(),authMethods:d.object({password:d.object({hash:d.string()}).optional(),google:d.object({id:d.string()}).optional(),github:d.object({id:d.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}},{key:{"emails.address":1,status:1}},{key:{"authMethods.google.id":1,status:1},sparse:true},{key:{"authMethods.github.id":1,status:1},sparse:true}]}),G=new w("_modelenceDisposableEmailDomains",{schema:{domain:d.string(),addedAt:d.date()},indexes:[{key:{domain:1},unique:true}]}),_=new w("_modelenceEmailVerificationTokens",{schema:{userId:d.objectId(),email:d.string().optional(),token:d.string(),createdAt:d.date(),expiresAt:d.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]}),v=new w("_modelenceResetPasswordTokens",{schema:{userId:d.objectId(),token:d.string(),createdAt:d.date(),expiresAt:d.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var Ke=new Map,F={authenticated:null,unauthenticated:null};function Ye(t,e){F.authenticated=e.authenticated,F.unauthenticated=e.unauthenticated;for(let[o,r]of Object.entries(t))Ke.set(o,r);}function ne(){return F.unauthenticated?[F.unauthenticated]:[]}function Xe(){return F.authenticated?[F.authenticated]:[]}function we(t,e){let o=e.find(r=>!uo(t,r));if(o)throw new Error(`Access denied - missing permission: '${o}'`)}function uo(t,e){for(let o of t){let r=Ke.get(o);if(r&&r.permissions.includes(e))return true}return false}async function T(t){let e=await Je(t),o=e.userId?await f.findOne({_id:new ObjectId(e.userId),status:{$nin:["deleted","disabled"]}}):null,r=o?{id:o._id.toString(),handle:o.handle,roles:o.roles||[],hasRole:i=>(o.roles||[]).includes(i),requireRole:i=>{if(!(o.roles||[]).includes(i))throw new Error(`Access denied - role '${i}' required`)}}:null,n=r?Xe():ne();return {user:r,session:e,roles:n}}var A=null;async function et(){if(A)return A;let t=j();if(!t)throw new Error("MongoDB URI is not set");A=new MongoClient(t,{maxPoolSize:20,driverInfo:{name:"Modelence",version:s.version},ignoreUndefined:true});try{return await A.connect(),await A.db("admin").command({ping:1}),console.log("Pinged your deployment. You successfully connected to MongoDB!"),A}catch(e){throw console.error(e),A=null,e}}function j(){let t=a$1("_system.mongodbUri");return t?String(t):void 0}function ie(){return A}var q=class{constructor(e){this.fetch=e.fetch,this.watch=e.watch;}};function fo(){return typeof window!="object"}function O(){if(!fo())throw new Error("This function can only be called on the server")}function se(t){return t.replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim()}var ae={};function be(t,e){return O(),nt(t),ce("query",t,e)}function tt(t,e){return O(),nt(t),ce("mutation",t,e)}function ot(t,e){return O(),it(t),ce("query",t,e)}function rt(t,e){return O(),it(t),ce("mutation",t,e)}function nt(t){if(t.toLowerCase().startsWith("_system."))throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${t})`)}function it(t){if(!t.toLowerCase().startsWith("_system."))throw new Error(`System method name must start with a prefix: '_system.' (${t})`)}function ce(t,e,o){if(O(),ae[e])throw new Error(`Method with name '${e}' is already defined.`);let r=typeof o=="function"?o:o.handler,n=typeof o=="function"?[]:o.permissions??[];ae[e]={type:t,name:e,handler:r,permissions:n};}async function st(t,e,o){O();let r=ae[t];if(!r)throw new Error(`Method with name '${t}' is not defined.`);let{type:n,handler:i}=r,s=k$1("method",`method:${t}`,{type:n,args:e}),a;try{we(o.roles,r.permissions),a=await i(e,o);}catch(c){throw s.end("error"),c}return s.end(),a}async function at(t,e,o){O();let r=ae[t];if(!r)throw new Error(`Method with name '${t}' is not defined.`);let{type:n,handler:i}=r;if(n!=="query")throw new Error("Live methods are only supported for queries");let s=k$1("method",`method:${t}:live`,{type:n,args:e}),a;try{if(we(o.roles,r.permissions),a=await i(e,o),!(a instanceof q))throw new Error(`Live query handler for '${t}' must return a LiveData object with fetch and watch functions.`)}catch(c){throw s.end("error"),c}return s.end(),a}var ho=z$1.object({subscriptionId:z$1.string().min(1),method:z$1.string().min(1),args:z$1.record(z$1.unknown()).default({}),authToken:z$1.string().nullish()}),go=z$1.object({subscriptionId:z$1.string().min(1)}),H=new Map;function yo(t){let e=H.get(t.id);return e||(e=new Map,H.set(t.id,e)),e}async function Ee(t,e){let o=ho.safeParse(e);if(!o.success){t.emit("liveQueryError",{subscriptionId:null,error:`Invalid payload: ${o.error.message}`});return}let{subscriptionId:r,method:n,args:i,authToken:s}=o.data,a;try{a={...await T(s??null),connectionInfo:t.data.connectionInfo};}catch(u){console.error("Failed to authenticate on subscribeLiveQuery:",u),t.emit("liveQueryError",{subscriptionId:r,error:"Authentication failed"});return}let c=yo(t),l=c.get(r);if(l)if(l.cleanup)try{l.cleanup();}catch(u){console.error("[LiveQuery] Error cleaning up existing subscription:",u);}else l.aborted=true;let p={cleanup:null};c.set(r,p);try{let u=await at(n,i,a),C=async()=>{let S=await u.fetch();p.aborted||t.emit("liveQueryData",{subscriptionId:r,data:S,typeMap:a$2(S)});},x=!0,L=!1,V=()=>{p.aborted||!x||L||(x=!1,L=!0,C().catch(S=>{p.aborted||(console.error(`[LiveQuery] Error fetching data for ${n}:`,S),t.emit("liveQueryError",{subscriptionId:r,error:S instanceof Error?S.message:String(S)}));}).finally(()=>{L=!1,V();}));},N=u.watch({publish:()=>{x=!0,V();}});if(p.aborted){if(N)try{N();}catch(S){console.error("[LiveQuery] Error cleaning up after disconnect during setup:",S);}return}p.cleanup=N||null,V();}catch(u){c.delete(r),console.error(`[LiveQuery] Error in ${n}:`,u),t.emit("liveQueryError",{subscriptionId:r,error:u instanceof Error?u.message:String(u)});}}function Se(t,e){let o=go.safeParse(e);if(!o.success){console.warn(`[LiveQuery] Invalid unsubscribe payload: ${o.error.message}`);return}let{subscriptionId:r}=o.data,n=H.get(t.id);if(!n)return;let i=n.get(r);if(i){if(i.cleanup)try{i.cleanup();}catch(s){console.error("[LiveQuery] Error in cleanup:",s);}else i.aborted=true;n.delete(r);}}function Ce(t){let e=H.get(t.id);if(e){for(let o of e.values())if(o.cleanup)try{o.cleanup();}catch(r){console.error("[LiveQuery] Error in cleanup on disconnect:",r);}else o.aborted=true;H.delete(t.id);}}var K=null,Eo="_modelenceSocketio";async function So({httpServer:t,channels:e}){let o=ie();console.log("Initializing Socket.IO server...");let r=null;if(o){r=o.db().collection(Eo);try{await r.createIndex({createdAt:1},{expireAfterSeconds:3600,background:!0});}catch(n){console.error("Failed to create index on MongoDB collection for Socket.IO:",n);}}K=new Server(t,{cors:{origin:"*",methods:["GET","POST"]},adapter:r?createAdapter(r):void 0,transports:["polling","websocket"],allowUpgrades:true,perMessageDeflate:false}),K.on("error",n=>{console.error("Socket.IO error:",n);}),K.use(async(n,i)=>{n.data={connectionInfo:{ip:n.handshake.address,userAgent:n.handshake.headers["user-agent"],acceptLanguage:n.handshake.headers["accept-language"],referrer:n.handshake.headers.referer}},i();}),K.on("connection",n=>{console.log("Socket.IO client connected"),n.on("disconnect",()=>{console.log("Socket.IO client disconnected"),Ce(n);}),n.on("joinChannel",async i=>{let{channelName:s,authToken:a}=i,c;try{c=await T(a??null);}catch(u){console.error("Failed to authenticate on joinChannel:",u),n.emit("joinError",{channel:s,error:"Authentication failed"});return}let[l]=s.split(":"),p=false;for(let u of e)if(u.category===l){(!u.canAccessChannel||await u.canAccessChannel(c))&&(n.join(s),p=true,n.emit("joinedChannel",s));break}p||n.emit("joinError",{channel:s,error:"Access denied"});}),n.on("leaveChannel",i=>{n.leave(i),console.log(`User ${n.id} left channel ${i}`),n.emit("leftChannel",i);}),n.on("subscribeLiveQuery",i=>Ee(n,i)),n.on("unsubscribeLiveQuery",i=>Se(n,i));}),console.log("Socket.IO server initialized");}function Co({category:t,id:e,data:o}){K?.to(`${t}:${e}`).emit(t,o);}var ct={init:So,broadcast:Co};async function lt(t){let e=t.toLowerCase().trim().split("@");if(e.length!==2)return false;let o=e[1];return !!await G.findOne({domain:o})}var dt={interval:a.days(1),async handler(){let t=await fetch("https://disposable.github.io/disposable-email-domains/domains.txt");if(!t.ok)throw new Error(`HTTP ${t.status}: ${t.statusText}`);let o=(await t.text()).split(`
2
+ `).map(i=>i.trim().toLowerCase()).filter(i=>i.length>0),r=new Date,n=500;for(let i=0;i<o.length;i+=n){let s=o.slice(i,i+n);try{await G.insertMany(s.map(a=>({domain:a,addedAt:r})));}catch(a){a&&typeof a=="object"&&"name"in a&&a.name;}}}};var xe=Object.freeze({});function ut(t){xe=Object.freeze(Object.assign({},xe,t));}function b(){return xe}function pt({name:t,email:e,verificationUrl:o}){return `
3
3
  <p>Hi${t?` ${t}`:""},</p>
4
4
  <p>Please verify your email address ${e} by clicking the link below:</p>
5
5
  <p><a href="${o}">${o}</a></p>
6
6
  <p>If you did not request this, please ignore this email.</p>
7
- `}var xe=Object.freeze({});function mt(t){xe=Object.freeze(Object.assign({},xe,t));}function h(){return xe}async function ft(t){let e=process.env.MODELENCE_SITE_URL,o=b().emailVerifiedRedirectUrl||e||"/";try{let r=z$1.string().parse(t.query.token),n=await _.findOne({token:r,expiresAt:{$gt:new Date}});if(!n)throw new Error("Invalid or expired verification token");if(!await p.findOne({_id:n.userId}))throw new Error("User not found");let s=n.email;if(!s)throw new Error("Email not found in token");if((await p.updateOne({_id:n.userId,"emails.address":s,"emails.verified":{$ne:!0}},{$set:{"emails.$.verified":!0}})).matchedCount===0)throw await p.findOne({_id:n.userId,"emails.address":s})?new Error("Email is already verified"):new Error("Email address not found for this user");await _.deleteOne({_id:n._id}),h().onAfterEmailVerification?.({provider:"email",user:await p.findOne({"emails.address":n?.email}),session:null,connectionInfo:{baseUrl:e,ip:t.req.ip||t.req.socket.remoteAddress,userAgent:t.headers["user-agent"],acceptLanguage:t.headers["accept-language"],referrer:t.headers.referer}});}catch(r){if(r instanceof Error)return h().onEmailVerificationError?.({provider:"email",error:r,session:null,connectionInfo:{baseUrl:e,ip:t.req.ip||t.req.socket.remoteAddress,userAgent:t.headers["user-agent"],acceptLanguage:t.headers["accept-language"],referrer:t.headers.referer}}),console.error("Error verifying email:",r),{status:301,redirect:`${o}?status=error&message=${encodeURIComponent(r.message)}`}}return {status:301,redirect:`${o}?status=verified`}}async function ae({userId:t,email:e,baseUrl:o=process.env.MODELENCE_SITE_URL}){if(b().provider){let r=b().provider,n=randomBytes(32).toString("hex"),i=new Date(Date.now()+a.hours(24));await _.insertOne({userId:t,email:e,token:n,createdAt:new Date,expiresAt:i});let s=`${o}/api/_internal/auth/verify-email?token=${n}`,c=(b()?.verification?.template||pt)({name:"",email:e,verificationUrl:s}),l=ne(c);await r?.sendEmail({to:e,from:b()?.from||"noreply@modelence.com",subject:b()?.verification?.subject||"Verify your email address",text:l,html:c});}}function ce(t){return z$1.string().min(8,{message:"Password must contain at least 8 characters"}).parse(t)}function q(t){return z$1.string().email({message:"Invalid email address"}).parse(t)}async function yt(t,{user:e,session:o,connectionInfo:r}){try{if(!o)throw new Error("Session is not initialized");let n=r?.ip;n&&await j({bucket:"signin",type:"ip",value:n});let i=q(t.email),s=z$1.string().parse(t.password),a=await p.findOne({"emails.address":i,status:{$nin:["deleted","disabled"]}},{collation:{locale:"en",strength:2}}),c=a?.authMethods?.password?.hash;if(!c)throw gt();if(!a.emails?.find(m=>m.address===i)?.verified&&b()?.provider){if(n)try{await j({bucket:"verification",type:"user",value:a._id.toString()});}catch{throw new Error("Your email address hasn't been verified yet. Please use the verification email we've send earlier to your inbox.")}throw await ae({userId:a?._id,email:i,baseUrl:r?.baseUrl}),new Error("Your email address hasn't been verified yet. We've sent a new verification email to your inbox.")}if(!await To.compare(s,c))throw gt();return await Ge(o.authToken,a._id),h().onAfterLogin?.({provider:"email",user:a,session:o,connectionInfo:r}),h().login?.onSuccess?.(a),{user:{id:a._id,handle:a.handle,roles:a.roles||[]}}}catch(n){throw n instanceof Error&&(h().onLoginError?.({provider:"email",error:n,session:o,connectionInfo:r}),h().login?.onError?.(n)),n}}async function wt(t,{session:e}){if(!e)throw new Error("Session is not initialized");await Qe(e.authToken);}function gt(){return new Error("Incorrect email/password combination")}async function bt(t,{user:e}){if(!e)throw new Error("Not authenticated");let o=await p.requireById(e.id);return {handle:o.handle,emails:o.emails,authMethods:Object.keys(o.authMethods||{})}}var H=new w("_modelenceRateLimits",{schema:{bucket:d.string(),type:d.enum(["ip","user"]),value:d.string(),windowMs:d.number(),windowStart:d.date(),windowCount:d.number(),prevWindowCount:d.number(),expiresAt:d.date()},indexes:[{key:{bucket:1,type:1,value:1,windowMs:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var ve=[];function Et(t){if(ve.length>0)throw new Error("Duplicate call to initRateLimits - already initialized");ve=t;}async function j(t){let{bucket:e,type:o,value:r}=t,n=ve.filter(i=>i.bucket===e&&i.type===o);for(let i of n)await _o(i,r);}async function _o(t,e,o){let r=()=>new d$1(`Rate limit exceeded for ${t.bucket}`),n=await H.findOne({bucket:t.bucket,type:t.type,value:e,windowMs:t.window}),i=Date.now(),s=Math.floor(i/t.window)*t.window,{count:a,modifier:c}=n?ko(n,s,i):{count:0,modifier:{$setOnInsert:{windowStart:new Date(s),windowCount:1,prevWindowCount:0,expiresAt:new Date(s+t.window+t.window)}}};if(a>=t.limit)throw r();await H.upsertOne({bucket:t.bucket,type:t.type,value:e,windowMs:t.window},c);}function ko(t,e,o){let r=e-t.windowMs;if(t.windowStart.getTime()===e){let n=t.windowCount,i=t.prevWindowCount,s=1-(o-e)/t.windowMs;return {count:Math.round(n+i*s),modifier:{$inc:{windowCount:1},$setOnInsert:{windowStart:new Date(e),prevWindowCount:0,expiresAt:new Date(e+t.windowMs+t.windowMs)}}}}if(t.windowStart.getTime()===r){let n=1-(o-e)/t.windowMs;return {count:Math.round(t.windowCount*n),modifier:{$set:{windowStart:new Date(e),windowCount:1,prevWindowCount:t.windowCount,expiresAt:new Date(e+t.windowMs+t.windowMs)}}}}return {count:0,modifier:{$set:{windowStart:new Date(e),windowCount:1,prevWindowCount:0,expiresAt:new Date(e+t.windowMs+t.windowMs)}}}}async function St(t,{user:e,session:o,connectionInfo:r}){try{let n=q(t.email),i=ce(t.password),s=r?.ip;if(s&&await j({bucket:"signupAttempt",type:"ip",value:s}),await lt(n))throw new Error("Please use a permanent email address");let a=await p.findOne({"emails.address":n},{collation:{locale:"en",strength:2}});if(a){let m=a.emails?.find(S=>S.address===n);throw a.status==="disabled"?new Error("User is marked for deletion, please contact support if you want to restore the account."):new Error(`User with email already exists: ${m?.address}`)}s&&await j({bucket:"signup",type:"ip",value:s});let c=await To.hash(i,10),l=await p.insertOne({handle:n,status:"active",emails:[{address:n,verified:!1}],createdAt:new Date,authMethods:{password:{hash:c}}}),f=await p.findOne({_id:l.insertedId},{readPreference:"primary"});if(!f)throw new Error("User not found");return await ae({userId:l?.insertedId,email:n,baseUrl:r?.baseUrl}),h().onAfterSignup?.({provider:"email",user:f,session:o,connectionInfo:r}),h().signup?.onSuccess?.(f),l.insertedId}catch(n){throw n instanceof Error&&(h().onSignupError?.({provider:"email",error:n,session:o,connectionInfo:r}),h().signup?.onError?.(n)),n}}function Io(t,e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${t}${e.startsWith("/")?"":"/"}${e}`:t}function Lo({email:t,resetUrl:e}){return `
7
+ `}var ve=Object.freeze({});function mt(t){ve=Object.freeze(Object.assign({},ve,t));}function h(){return ve}async function ft(t){let e=process.env.MODELENCE_SITE_URL,o=b().emailVerifiedRedirectUrl||e||"/";try{let r=z$1.string().parse(t.query.token),n=await _.findOne({token:r,expiresAt:{$gt:new Date}});if(!n)throw new Error("Invalid or expired verification token");if(!await f.findOne({_id:n.userId}))throw new Error("User not found");let s=n.email;if(!s)throw new Error("Email not found in token");if((await f.updateOne({_id:n.userId,"emails.address":s,"emails.verified":{$ne:!0}},{$set:{"emails.$.verified":!0}})).matchedCount===0)throw await f.findOne({_id:n.userId,"emails.address":s})?new Error("Email is already verified"):new Error("Email address not found for this user");await _.deleteOne({_id:n._id}),h().onAfterEmailVerification?.({provider:"email",user:await f.findOne({"emails.address":n?.email}),session:null,connectionInfo:{baseUrl:e,ip:t.req.ip||t.req.socket.remoteAddress,userAgent:t.headers["user-agent"],acceptLanguage:t.headers["accept-language"],referrer:t.headers.referer}});}catch(r){if(r instanceof Error)return h().onEmailVerificationError?.({provider:"email",error:r,session:null,connectionInfo:{baseUrl:e,ip:t.req.ip||t.req.socket.remoteAddress,userAgent:t.headers["user-agent"],acceptLanguage:t.headers["accept-language"],referrer:t.headers.referer}}),console.error("Error verifying email:",r),{status:301,redirect:`${o}?status=error&message=${encodeURIComponent(r.message)}`}}return {status:301,redirect:`${o}?status=verified`}}async function le({userId:t,email:e,baseUrl:o=process.env.MODELENCE_SITE_URL}){if(b().provider){let r=b().provider,n=randomBytes(32).toString("hex"),i=new Date(Date.now()+a.hours(24));await _.insertOne({userId:t,email:e,token:n,createdAt:new Date,expiresAt:i});let s=`${o}/api/_internal/auth/verify-email?token=${n}`,c=(b()?.verification?.template||pt)({name:"",email:e,verificationUrl:s}),l=se(c);await r?.sendEmail({to:e,from:b()?.from||"noreply@modelence.com",subject:b()?.verification?.subject||"Verify your email address",text:l,html:c});}}function de(t){return z$1.string().min(8,{message:"Password must contain at least 8 characters"}).parse(t)}function W(t){return z$1.string().email({message:"Invalid email address"}).parse(t)}async function yt(t,{user:e,session:o,connectionInfo:r}){try{if(!o)throw new Error("Session is not initialized");let n=r?.ip;n&&await U({bucket:"signin",type:"ip",value:n});let i=W(t.email),s=z$1.string().parse(t.password),a=await f.findOne({"emails.address":i,status:{$nin:["deleted","disabled"]}},{collation:{locale:"en",strength:2}}),c=a?.authMethods?.password?.hash;if(!c)throw gt();if(!a.emails?.find(u=>u.address===i)?.verified&&b()?.provider){if(n)try{await U({bucket:"verification",type:"user",value:a._id.toString()});}catch{throw new Error("Your email address hasn't been verified yet. Please use the verification email we've send earlier to your inbox.")}throw await le({userId:a?._id,email:i,baseUrl:r?.baseUrl}),new Error("Your email address hasn't been verified yet. We've sent a new verification email to your inbox.")}if(!await To.compare(s,c))throw gt();return await Qe(o.authToken,a._id),h().onAfterLogin?.({provider:"email",user:a,session:o,connectionInfo:r}),h().login?.onSuccess?.(a),{user:{id:a._id,handle:a.handle,roles:a.roles||[]}}}catch(n){throw n instanceof Error&&(h().onLoginError?.({provider:"email",error:n,session:o,connectionInfo:r}),h().login?.onError?.(n)),n}}async function wt(t,{session:e}){if(!e)throw new Error("Session is not initialized");await Ge(e.authToken);}function gt(){return new Error("Incorrect email/password combination")}async function bt(t,{user:e}){if(!e)throw new Error("Not authenticated");let o=await f.requireById(e.id);return {handle:o.handle,emails:o.emails,authMethods:Object.keys(o.authMethods||{})}}var Y=new w("_modelenceRateLimits",{schema:{bucket:d.string(),type:d.enum(["ip","user"]),value:d.string(),windowMs:d.number(),windowStart:d.date(),windowCount:d.number(),prevWindowCount:d.number(),expiresAt:d.date()},indexes:[{key:{bucket:1,type:1,value:1,windowMs:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var Te=[];function Et(t){if(Te.length>0)throw new Error("Duplicate call to initRateLimits - already initialized");Te=t;}async function U(t){let{bucket:e,type:o,value:r}=t,n=Te.filter(i=>i.bucket===e&&i.type===o);for(let i of n)await ko(i,r);}async function ko(t,e,o){let r=()=>new d$1(`Rate limit exceeded for ${t.bucket}`),n=await Y.findOne({bucket:t.bucket,type:t.type,value:e,windowMs:t.window}),i=Date.now(),s=Math.floor(i/t.window)*t.window,{count:a,modifier:c}=n?_o(n,s,i):{count:0,modifier:{$setOnInsert:{windowStart:new Date(s),windowCount:1,prevWindowCount:0,expiresAt:new Date(s+t.window+t.window)}}};if(a>=t.limit)throw r();await Y.upsertOne({bucket:t.bucket,type:t.type,value:e,windowMs:t.window},c);}function _o(t,e,o){let r=e-t.windowMs;if(t.windowStart.getTime()===e){let n=t.windowCount,i=t.prevWindowCount,s=1-(o-e)/t.windowMs;return {count:Math.round(n+i*s),modifier:{$inc:{windowCount:1},$setOnInsert:{windowStart:new Date(e),prevWindowCount:0,expiresAt:new Date(e+t.windowMs+t.windowMs)}}}}if(t.windowStart.getTime()===r){let n=1-(o-e)/t.windowMs;return {count:Math.round(t.windowCount*n),modifier:{$set:{windowStart:new Date(e),windowCount:1,prevWindowCount:t.windowCount,expiresAt:new Date(e+t.windowMs+t.windowMs)}}}}return {count:0,modifier:{$set:{windowStart:new Date(e),windowCount:1,prevWindowCount:0,expiresAt:new Date(e+t.windowMs+t.windowMs)}}}}async function St(t,{user:e,session:o,connectionInfo:r}){try{let n=W(t.email),i=de(t.password),s=r?.ip;if(s&&await U({bucket:"signupAttempt",type:"ip",value:s}),await lt(n))throw new Error("Please use a permanent email address");let a=await f.findOne({"emails.address":n},{collation:{locale:"en",strength:2}});if(a){let u=a.emails?.find(C=>C.address===n);throw a.status==="disabled"?new Error("User is marked for deletion, please contact support if you want to restore the account."):new Error(`User with email already exists: ${u?.address}`)}s&&await U({bucket:"signup",type:"ip",value:s});let c=await To.hash(i,10),l=await f.insertOne({handle:n,status:"active",emails:[{address:n,verified:!1}],createdAt:new Date,authMethods:{password:{hash:c}}}),p=await f.findOne({_id:l.insertedId},{readPreference:"primary"});if(!p)throw new Error("User not found");return await le({userId:l?.insertedId,email:n,baseUrl:r?.baseUrl}),h().onAfterSignup?.({provider:"email",user:p,session:o,connectionInfo:r}),h().signup?.onSuccess?.(p),l.insertedId}catch(n){throw n instanceof Error&&(h().onSignupError?.({provider:"email",error:n,session:o,connectionInfo:r}),h().signup?.onError?.(n)),n}}function Io(t,e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${t}${e.startsWith("/")?"":"/"}${e}`:t}function Lo({email:t,resetUrl:e}){return `
8
8
  <p>Hi,</p>
9
9
  <p>We received a request to reset your password for ${t}.</p>
10
10
  <p>Click the link below to reset your password:</p>
11
11
  <p><a href="${e}">${e}</a></p>
12
12
  <p>This link will expire in 1 hour.</p>
13
13
  <p>If you did not request this password reset, please ignore this email.</p>
14
- `}var Te={success:true,message:"If an account with that email exists, a password reset link has been sent"};async function Ct(t,{connectionInfo:e}){let o=q(t.email),r=await p.findOne({"emails.address":o,status:{$nin:["deleted","disabled"]}},{collation:{locale:"en",strength:2}});if(!r||!r.authMethods?.password)return Te;let n=b().provider;if(!n)throw new Error("Email provider is not configured");let i=randomBytes(32).toString("hex"),s=Date.now(),a$1=new Date(s),c=new Date(s+a.hours(1));await v.insertOne({userId:r._id,token:i,createdAt:a$1,expiresAt:c});let l=process.env.MODELENCE_SITE_URL||e?.baseUrl,m=`${Io(l,b().passwordReset?.redirectUrl)}?token=${i}`,x=(b()?.passwordReset?.template||Lo)({email:o,resetUrl:m,name:""}),I=ne(x);return await n.sendEmail({to:o,from:b()?.from||"noreply@modelence.com",subject:b()?.passwordReset?.subject||"Reset your password",text:I,html:x}),Te}async function xt(t,{}){let e=z$1.string().parse(t.token),o=ce(t.password),r=await v.findOne({token:e});if(!r)throw new Error("Invalid or expired reset token");if(r.expiresAt<new Date)throw await v.deleteOne({token:e}),new Error("Reset token has expired");let n=await p.findOne({_id:r.userId});if(!n)throw new Error("User not found");let i=await To.hash(o,10);return await p.updateOne({_id:n._id},{$set:{"authMethods.password.hash":i}}),await v.deleteOne({token:e}),{success:true,message:"Password has been reset successfully"}}var vt=new E("_system.user",{stores:[p,J,_,v],queries:{getOwnProfile:bt},mutations:{signupWithPassword:St,loginWithPassword:yt,logout:wt,sendResetPasswordToken:Ct,resetPassword:xt},cronJobs:{updateDisposableEmailList:dt},rateLimits:[{bucket:"signup",type:"ip",window:a.minutes(15),limit:20},{bucket:"signup",type:"ip",window:a.days(1),limit:200},{bucket:"signupAttempt",type:"ip",window:a.minutes(15),limit:50},{bucket:"signupAttempt",type:"ip",window:a.days(1),limit:500},{bucket:"signin",type:"ip",window:a.minutes(15),limit:50},{bucket:"signin",type:"ip",window:a.days(1),limit:500},{bucket:"verification",type:"user",window:a.minutes(15),limit:3},{bucket:"verification",type:"user",window:a.days(1),limit:10}],configSchema:{"auth.email.enabled":{type:"boolean",isPublic:true,default:true},"auth.email.from":{type:"string",isPublic:false,default:""},"auth.email.verification":{type:"boolean",isPublic:true,default:false},"auth.google.enabled":{type:"boolean",isPublic:true,default:false},"auth.google.clientId":{type:"string",isPublic:false,default:""},"auth.google.clientSecret":{type:"secret",isPublic:false,default:""},"auth.github.enabled":{type:"boolean",isPublic:true,default:false},"auth.github.clientId":{type:"string",isPublic:false,default:""},"auth.github.clientSecret":{type:"secret",isPublic:false,default:""}},routes:[{path:"/api/_internal/auth/verify-email",handlers:{get:ft}}]});async function Tt({configSchema:t,cronJobsMetadata:e,stores:o}){let r=process.env.MODELENCE_CONTAINER_ID;if(!r)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set");try{let n=Object.values(o).map(s=>({name:s.getName(),schema:s.getSerializedSchema(),collections:[s.getName()],version:2})),i=await De("/api/connect","POST",{hostname:Po.hostname(),containerId:r,dataModels:n,configSchema:t,cronJobsMetadata:e});if(i.status==="error")throw new Error(i.error);return console.log("Successfully connected to Modelence Cloud"),i}catch(n){throw console.error("Unable to connect to Modelence Cloud:",n),n}}async function Dt(){return await De("/api/configs","GET")}async function _t(){return await De("/api/sync","POST",{containerId:process.env.MODELENCE_CONTAINER_ID})}async function De(t,e,o){let{MODELENCE_SERVICE_ENDPOINT:r,MODELENCE_SERVICE_TOKEN:n}=process.env;if(!r)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set");let i=await fetch(`${r}${t}`,{method:e,headers:{Authorization:`Bearer ${n}`,...o?{"Content-Type":"application/json"}:{}},body:o?JSON.stringify(o):void 0});if(!i.ok){let s=await i.text();try{let a=JSON.parse(s);throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${i.status}, ${a?.error}`)}catch{throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${i.status}, ${s}`)}}return await i.json()}var _e=false,Uo=a.seconds(10);function kt(){setInterval(async()=>{if(!_e){_e=true;try{await _t();}catch(t){console.error("Error syncing status",t);}try{await jo();}catch(t){console.error("Error syncing config",t);}_e=false;}},Uo);}async function jo(){let{configs:t}=await Dt();c(t);}var K=new w("_modelenceLocks",{schema:{resource:d.string(),instanceId:d.string(),acquiredAt:d.date()},indexes:[{key:{resource:1},unique:true},{key:{resource:1,instanceId:1}},{key:{resource:1,acquiredAt:1}}]});var W={},At=a.seconds(10),Ot=randomBytes(32).toString("base64url"),No=a.seconds(30);async function le(t,{lockDuration:e=No,successfulLockCacheDuration:o=At,failedLockCacheDuration:r=At,instanceId:n=Ot}={}){let i=Date.now();if(W[t]&&i<W[t].expiresAt)return W[t].value;let s=new Date(i-e);h$1(`Attempting to acquire lock: ${t}`,{source:"lock",resource:t,instanceId:n});try{let a=await K.upsertOne({$or:[{resource:t,instanceId:n},{resource:t,acquiredAt:{$lt:s}}]},{$set:{resource:t,instanceId:n,acquiredAt:new Date}}),c=a.upsertedCount>0||a.modifiedCount>0;return W[t]={value:c,expiresAt:i+(c?o:r)},c?h$1(`Lock acquired: ${t}`,{source:"lock",resource:t,instanceId:n}):h$1(`Failed to acquire lock (already held): ${t}`,{source:"lock",resource:t,instanceId:n}),c}catch{return W[t]={value:false,expiresAt:i+r},h$1(`Failed to acquire lock (already held): ${t}`,{source:"lock",resource:t,instanceId:n}),false}}async function Rt(t,{instanceId:e=Ot}={}){let o=await K.deleteOne({resource:t,instanceId:e});return delete W[t],o.deletedCount>0}var zo=a.minutes(1),$={},ke=null,Ae=new w("_modelenceCronJobs",{schema:{alias:d.string(),lastStartDate:d.date().optional()},indexes:[{key:{alias:1},unique:true,background:true}]});function It(t,{description:e="",interval:o,timeout:r=zo,handler:n}){if($[t])throw new Error(`Duplicate cron job declaration: '${t}' already exists`);if(ke)throw new Error(`Unable to add a cron job - cron jobs have already been initialized: [${t}]`);if(o<a.seconds(5))throw new Error(`Cron job interval should not be less than 5 second [${t}]`);if(r>a.days(1))throw new Error(`Cron job timeout should not be longer than 1 day [${t}]`);$[t]={alias:t,params:{description:e,interval:o,timeout:r},handler:n,state:{isRunning:false}};}async function Lt(){if(ke)throw new Error("Cron jobs already started");let t=Object.keys($);if(t.length>0){let e={alias:{$in:t}},o=await Ae.fetch(e),r=Date.now();o.forEach(n=>{let i=$[n.alias];i&&(i.state.scheduledRunTs=n.lastStartDate?n.lastStartDate.getTime()+i.params.interval:r);}),Object.values($).forEach(n=>{n.state.scheduledRunTs||(n.state.scheduledRunTs=r);}),ke=setInterval(Fo,a.seconds(1));}}async function Fo(){let t=Date.now();await le("cron",{successfulLockCacheDuration:a.seconds(10),failedLockCacheDuration:a.seconds(30)})&&Object.values($).forEach(async o=>{let{params:r,state:n}=o;if(n.isRunning){n.startTs&&n.startTs+r.timeout<t&&(n.isRunning=false);return}n.scheduledRunTs&&n.scheduledRunTs<=t&&await qo(o);});}async function qo(t){let{alias:e,params:o,handler:r,state:n}=t;n.isRunning=true,n.startTs=Date.now(),await Ae.updateOne({alias:e},{$set:{lastStartDate:new Date(n.startTs)}});let i=k$1("cron",`cron:${e}`);try{await r(),Mt(n,o),i.end("success");}catch(s){Mt(n,o);let a=s instanceof Error?s:new Error(String(s));l(a),i.end("error"),console.error(`Error in cron job '${e}':`,s);}}function Mt(t,e){t.scheduledRunTs=t.startTs?t.startTs+e.interval:Date.now(),t.startTs=void 0,t.isRunning=false;}function Pt(){return Object.values($).map(({alias:t,params:e})=>({alias:t,description:e.description,interval:e.interval,timeout:e.timeout}))}var Ut=new E("_system.cron",{stores:[Ae]});var Oe=new E("_system.lock",{stores:[K]});var Y=new w("_modelenceMigrations",{schema:{version:d.number(),status:d.enum(["completed","failed"]),description:d.string().optional(),output:d.string().optional(),appliedAt:d.date()},indexes:[{key:{version:1},unique:true},{key:{version:1,status:1}}]});async function Wo(t){if(t.length===0)return;if(!await le("migrations")){i("Another instance is running migrations. Skipping migration run.",{source:"migrations"});return}let o=t.map(({version:s})=>s),r=await Y.fetch({version:{$in:o}}),n=new Set(r.map(({version:s})=>s)),i$1=t.filter(({version:s})=>!n.has(s));if(i$1.length!==0){i(`Running migrations (${i$1.length})...`,{source:"migrations"});for(let{version:s,description:a,handler:c}of i$1){i(`Running migration v${s}: ${a}`,{source:"migrations"});try{let f=(await c()||"").toString().trim(),m=15*1024*1024,S=f.length>m?f.slice(0,m)+`
15
- [Output truncated - exceeded size limit]`:f;await Y.upsertOne({version:s},{$set:{version:s,status:"completed",description:a,output:S,appliedAt:new Date}}),i(`Migration v${s} complete`,{source:"migrations"});}catch(l){l instanceof Error&&(await Y.upsertOne({version:s},{$set:{version:s,status:"failed",description:a,output:l.message||"",appliedAt:new Date}}),i(`Migration v${s} is failed: ${l.message}`,{source:"migrations"}));}}await Rt("migrations");}}function jt(t){setTimeout(()=>{Wo(t).catch(e=>{console.error("Error running migrations:",e);});},0);}var $t=new E("_system.migration",{stores:[Y]});var Nt=new E("_system.rateLimit",{stores:[H]});var zt=new E("_system",{configSchema:{mongodbUrl:{type:"string",isPublic:false,default:""},env:{type:"string",isPublic:true,default:""},"site.url":{type:"string",isPublic:true,default:""}}});var Me=class{async init(){this.config=await Yo(),this.isDev()&&(console.log("Starting Vite dev server..."),this.viteServer=await createServer(this.config));}middlewares(){if(this.isDev())return this.viteServer?.middlewares??[];let e=[M.static("./.modelence/build/client".replace(/\\/g,"/"))];return this.config?.publicDir&&e.push(M.static(this.config.publicDir)),e}handler(e,o){if(this.isDev())try{o.sendFile("index.html",{root:"./src/client"});}catch(r){console.error("Error serving index.html:",r),o.status(500).send("Internal Server Error");}else o.sendFile("index.html",{root:"./.modelence/build/client".replace(/\\/g,"/")});}isDev(){return process.env.NODE_ENV!=="production"}};async function Ho(){let t=process.cwd();try{return (await loadConfigFromFile({command:"serve",mode:"development"},void 0,t))?.config||{}}catch(e){return console.warn("Could not load vite config:",e),{}}}function Ko(t,e){let o=mergeConfig(t,e);if(o.plugins&&Array.isArray(o.plugins)){let r=new Set;o.plugins=o.plugins.flat().filter(n=>{if(!n||typeof n!="object"||Array.isArray(n))return true;let i=n.name;return !i||r.has(i)?false:(r.add(i),true)}).reverse(),o.plugins.reverse();}return o}async function Yo(){let t=process.cwd(),e=await Ho(),o=[".eslintrc.js",".eslintrc.json",".eslintrc","eslint.config.js",".eslintrc.yml",".eslintrc.yaml"].find(i=>Qo.existsSync(Re.join(t,i))),r=[Go(),Xo()];if(o){let i=(await import('vite-plugin-eslint')).default;r.push(i({failOnError:false,include:["src/**/*.js","src/**/*.jsx","src/**/*.ts","src/**/*.tsx"],cwd:t,overrideConfigFile:Re.resolve(t,o)}));}let n=defineConfig({plugins:r,build:{outDir:".modelence/build/client".replace(/\\/g,"/"),emptyOutDir:true},server:{middlewareMode:true},root:"./src/client",resolve:{alias:{"@":Re.resolve(t,"src").replace(/\\/g,"/")}}});return Ko(n,e)}function Xo(){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}}}var qt=new Me;async function Wt(t,e){let{authToken:o}=await ge(e);t.cookie("authToken",o,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"strict"}),t.status(301),t.redirect("/");}function Z(t){return `${a$1("_system.site.url")}/api/_internal/auth/${t}/callback`}async function de(t,e,o){let r=await p.findOne({[`authMethods.${o.providerName}.id`]:o.id}),{session:n,connectionInfo:i}=await Ie(t);try{if(r){await Wt(e,r._id),h().onAfterLogin?.({provider:o.providerName,user:r,session:n,connectionInfo:i}),h().login?.onSuccess?.(r);return}}catch(s){throw s instanceof Error&&(h().login?.onError?.(s),h().onLoginError?.({provider:o.providerName,error:s,session:n,connectionInfo:i})),s}try{if(!o.email){e.status(400).json({error:`Email address is required for ${o.providerName} authentication.`});return}if(await p.findOne({"emails.address":o.email},{collation:{locale:"en",strength:2}})){e.status(400).json({error:"User with this email already exists. Please log in instead."});return}let a=await p.insertOne({handle:o.email,status:"active",emails:[{address:o.email,verified:o.emailVerified}],createdAt:new Date,authMethods:{[o.providerName]:{id:o.id}}});await Wt(e,a.insertedId);let c=await p.findOne({_id:a.insertedId},{readPreference:"primary"});c&&(h().onAfterSignup?.({provider:o.providerName,user:c,session:n,connectionInfo:i}),h().signup?.onSuccess?.(c));}catch(s){throw s instanceof Error&&(h().onSignupError?.({provider:o.providerName,error:s,session:n,connectionInfo:i}),h().signup?.onError?.(s)),s}}function ue(t){return !t||typeof t!="string"?null:t}async function or(t,e,o,r){let n=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code:t,client_id:e,client_secret:o,redirect_uri:r,grant_type:"authorization_code"})});if(!n.ok)throw new Error(`Failed to exchange code for token: ${n.statusText}`);return n.json()}async function rr(t){let e=await fetch("https://www.googleapis.com/oauth2/v2/userinfo",{headers:{Authorization:`Bearer ${t}`}});if(!e.ok)throw new Error(`Failed to fetch user info: ${e.statusText}`);return e.json()}async function nr(t,e){let o=ue(t.query.code),r=t.query.state,n=t.cookies.authStateGoogle;if(!o){e.status(400).json({error:"Missing authorization code"});return}if(!r||!n||r!==n){e.status(400).json({error:"Invalid OAuth state - possible CSRF attack"});return}e.clearCookie("authStateGoogle");let i=String(a$1("_system.user.auth.google.clientId")),s=String(a$1("_system.user.auth.google.clientSecret")),a=Z("google");try{let c=await or(o,i,s,a),l=await rr(c.access_token),f={id:l.id,email:l.email,emailVerified:l.verified_email,providerName:"google"};await de(t,e,f);}catch(c){console.error("Google OAuth error:",c),e.status(500).json({error:"Authentication failed"});}}function ir(){let t=Router(),e=(o,r,n)=>{let i=!!a$1("_system.user.auth.google.enabled"),s=String(a$1("_system.user.auth.google.clientId")),a=String(a$1("_system.user.auth.google.clientSecret"));if(!i||!s||!a){r.status(503).json({error:"Google authentication is not configured"});return}n();};return t.get("/api/_internal/auth/google",e,(o,r)=>{let n=String(a$1("_system.user.auth.google.clientId")),i=Z("google"),s=randomBytes(32).toString("hex");r.cookie("authStateGoogle",s,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"lax",maxAge:a.minutes(10)});let a$2=new URL("https://accounts.google.com/o/oauth2/v2/auth");a$2.searchParams.append("client_id",n),a$2.searchParams.append("redirect_uri",i),a$2.searchParams.append("response_type","code"),a$2.searchParams.append("scope","profile email"),a$2.searchParams.append("access_type","online"),a$2.searchParams.append("state",s),r.redirect(a$2.toString());}),t.get("/api/_internal/auth/google/callback",e,nr),t}var Zt=ir;async function cr(t,e,o,r){let n=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({client_id:e,client_secret:o,code:t,redirect_uri:r})});if(!n.ok)throw new Error(`Failed to exchange code for token: ${n.statusText}`);return n.json()}async function lr(t){let e=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${t}`,Accept:"application/vnd.github.v3+json"}});if(!e.ok)throw new Error(`Failed to fetch user info: ${e.statusText}`);return e.json()}async function dr(t,e){let o=ue(t.query.code),r=t.query.state,n=t.cookies.authStateGithub;if(!o){e.status(400).json({error:"Missing authorization code"});return}if(!r||!n||r!==n){e.status(400).json({error:"Invalid OAuth state - possible CSRF attack"});return}e.clearCookie("authStateGithub");let i=String(a$1("_system.user.auth.github.clientId")),s=String(a$1("_system.user.auth.github.clientSecret")),a=Z("github");try{let c=await cr(o,i,s,a),l=await lr(c.access_token),f=l.email||"";if(!f){e.status(400).json({error:"Unable to retrieve email from GitHub. Please ensure your email is public or grant email permissions."});return}let m={id:String(l.id),email:f,emailVerified:!0,providerName:"github"};await de(t,e,m);}catch(c){console.error("GitHub OAuth error:",c),e.status(500).json({error:"Authentication failed"});}}function ur(){let t=Router(),e=(o,r,n)=>{let i=!!a$1("_system.user.auth.github.enabled"),s=String(a$1("_system.user.auth.github.clientId")),a=String(a$1("_system.user.auth.github.clientSecret"));if(!i||!s||!a){r.status(503).json({error:"GitHub authentication is not configured"});return}n();};return t.get("/api/_internal/auth/github",e,(o,r)=>{let n=String(a$1("_system.user.auth.github.clientId")),i=Z("github"),s=a$1("_system.user.auth.github.scopes"),a$2=s?String(s).split(",").map(f=>f.trim()).join(" "):"user:email",c=randomBytes(32).toString("hex");r.cookie("authStateGithub",c,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"lax",maxAge:a.minutes(10)});let l=new URL("https://github.com/login/oauth/authorize");l.searchParams.append("client_id",n),l.searchParams.append("redirect_uri",i),l.searchParams.append("scope",a$2),l.searchParams.append("state",c),r.redirect(l.toString());}),t.get("/api/_internal/auth/github/callback",e,dr),t}var Bt=ur;function Vt(t,e,o){return async(r,n,i)=>{let s=r.headers["x-modelence-auth-token"],a={session:null,user:null};if(typeof s=="string"&&P())try{let{session:l,user:f}=await k(s);a={session:l,user:f};}catch{}let c=k$1("route",`route:${t.toLowerCase()}:${e}`,{method:t,path:e,query:r.query,body:r.body,params:r.params});try{let l=await o({query:r.query,body:r.body,params:r.params,headers:r.headers,cookies:r.cookies,rawBody:Buffer.isBuffer(r.body)?r.body:void 0,req:r,res:n,next:i},a);c.end(),l&&(n.status(l.status||200),l.redirect&&n.redirect(l.redirect),l.headers&&Object.entries(l.headers).forEach(([f,m])=>{n.setHeader(f,m);}),n.send(l.data));}catch(l){c.end("error"),l instanceof a$3?n.status(l.status).send(l.message):(console.error(`Error in route handler: ${r.path}`),console.error(l),n.status(500).send(String(l)));}}}var Le=Object.freeze({});function Jt(t){Le=Object.freeze(Object.assign({},Le,t));}function pe(){return Le}function fr(t){let e=[];if(!t)return e.push(M.json({limit:"16mb"})),e.push(M.urlencoded({extended:true,limit:"16mb"})),e;if(t.json!==false){let o=typeof t.json=="object"?t.json:{limit:"16mb"};e.push(M.json(o));}if(t.urlencoded!==false){let o=typeof t.urlencoded=="object"?t.urlencoded:{extended:true,limit:"16mb"};e.push(M.urlencoded(o));}if(t.raw){let o=typeof t.raw=="object"?t.raw:{},r={limit:o.limit||"16mb",type:o.type||"*/*"};e.push(M.raw(r));}return e}function hr(t,e){for(let o of e)for(let r of o.routes){let{path:n,handlers:i,body:s}=r,a=fr(s);Object.entries(i).forEach(([c,l])=>{t[c](n,...a,Vt(c,n,l));});}}async function Gt(t,{combinedModules:e,channels:o}){let r=M();r.use(pr()),hr(r,e),r.use(M.json({limit:"16mb"})),r.use(M.urlencoded({extended:true,limit:"16mb"})),r.use(Zt()),r.use(Bt()),r.post("/api/_internal/method/:methodName(*)",async(a,c)=>{let{methodName:l}=a.params,f=await Ie(a);try{let m=await st(l,a.body.args,f);c.json({data:m,typeMap:a$2(m)});}catch(m){gr(c,l,m);}}),await t.init(),t.middlewares&&r.use(t.middlewares()),r.all("*",(a,c)=>t.handler(a,c)),process.on("unhandledRejection",(a,c)=>{console.error("Unhandled Promise Rejection:"),console.error(a instanceof Error?a.stack:a),console.error("Promise:",c);}),process.on("uncaughtException",a=>{console.error("Uncaught Exception:"),console.error(a.stack),console.trace("Full application stack:");});let n=mr.createServer(r),i$1=pe()?.provider;i$1&&i$1.init({httpServer:n,channels:o});let s=process.env.MODELENCE_PORT||process.env.PORT||3e3;n.listen(s,()=>{i("Application started",{source:"app"});let a=process.env.MODELENCE_SITE_URL||`http://localhost:${s}`;console.log(`
14
+ `}var De={success:true,message:"If an account with that email exists, a password reset link has been sent"};async function Ct(t,{connectionInfo:e}){let o=W(t.email),r=await f.findOne({"emails.address":o,status:{$nin:["deleted","disabled"]}},{collation:{locale:"en",strength:2}});if(!r||!r.authMethods?.password)return De;let n=b().provider;if(!n)throw new Error("Email provider is not configured");let i=randomBytes(32).toString("hex"),s=Date.now(),a$1=new Date(s),c=new Date(s+a.hours(1));await v.insertOne({userId:r._id,token:i,createdAt:a$1,expiresAt:c});let l=process.env.MODELENCE_SITE_URL||e?.baseUrl,u=`${Io(l,b().passwordReset?.redirectUrl)}?token=${i}`,x=(b()?.passwordReset?.template||Lo)({email:o,resetUrl:u,name:""}),L=se(x);return await n.sendEmail({to:o,from:b()?.from||"noreply@modelence.com",subject:b()?.passwordReset?.subject||"Reset your password",text:L,html:x}),De}async function xt(t,{}){let e=z$1.string().parse(t.token),o=de(t.password),r=await v.findOne({token:e});if(!r)throw new Error("Invalid or expired reset token");if(r.expiresAt<new Date)throw await v.deleteOne({token:e}),new Error("Reset token has expired");let n=await f.findOne({_id:r.userId});if(!n)throw new Error("User not found");let i=await To.hash(o,10);return await f.updateOne({_id:n._id},{$set:{"authMethods.password.hash":i}}),await v.deleteOne({token:e}),{success:true,message:"Password has been reset successfully"}}var vt=new E("_system.user",{stores:[f,G,_,v],queries:{getOwnProfile:bt},mutations:{signupWithPassword:St,loginWithPassword:yt,logout:wt,sendResetPasswordToken:Ct,resetPassword:xt},cronJobs:{updateDisposableEmailList:dt},rateLimits:[{bucket:"signup",type:"ip",window:a.minutes(15),limit:20},{bucket:"signup",type:"ip",window:a.days(1),limit:200},{bucket:"signupAttempt",type:"ip",window:a.minutes(15),limit:50},{bucket:"signupAttempt",type:"ip",window:a.days(1),limit:500},{bucket:"signin",type:"ip",window:a.minutes(15),limit:50},{bucket:"signin",type:"ip",window:a.days(1),limit:500},{bucket:"verification",type:"user",window:a.minutes(15),limit:3},{bucket:"verification",type:"user",window:a.days(1),limit:10}],configSchema:{"auth.email.enabled":{type:"boolean",isPublic:true,default:true},"auth.email.from":{type:"string",isPublic:false,default:""},"auth.email.verification":{type:"boolean",isPublic:true,default:false},"auth.google.enabled":{type:"boolean",isPublic:true,default:false},"auth.google.clientId":{type:"string",isPublic:false,default:""},"auth.google.clientSecret":{type:"secret",isPublic:false,default:""},"auth.github.enabled":{type:"boolean",isPublic:true,default:false},"auth.github.clientId":{type:"string",isPublic:false,default:""},"auth.github.clientSecret":{type:"secret",isPublic:false,default:""}},routes:[{path:"/api/_internal/auth/verify-email",handlers:{get:ft}}]});async function Tt({configSchema:t,cronJobsMetadata:e,stores:o}){let r=process.env.MODELENCE_CONTAINER_ID;if(!r)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set");try{let n=Object.values(o).map(s=>({name:s.getName(),schema:s.getSerializedSchema(),collections:[s.getName()],version:2})),i=await ke("/api/connect","POST",{hostname:Po.hostname(),containerId:r,dataModels:n,configSchema:t,cronJobsMetadata:e});if(i.status==="error")throw new Error(i.error);return console.log("Successfully connected to Modelence Cloud"),i}catch(n){throw console.error("Unable to connect to Modelence Cloud:",n),n}}async function Dt(){return await ke("/api/configs","GET")}async function kt(){return await ke("/api/sync","POST",{containerId:process.env.MODELENCE_CONTAINER_ID})}async function ke(t,e,o){let{MODELENCE_SERVICE_ENDPOINT:r,MODELENCE_SERVICE_TOKEN:n}=process.env;if(!r)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set");let i=await fetch(`${r}${t}`,{method:e,headers:{Authorization:`Bearer ${n}`,...o?{"Content-Type":"application/json"}:{}},body:o?JSON.stringify(o):void 0});if(!i.ok){let s=await i.text();try{let a=JSON.parse(s);throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${i.status}, ${a?.error}`)}catch{throw new Error(`Unable to connect to Modelence Cloud: HTTP status: ${i.status}, ${s}`)}}return await i.json()}var _e=false,jo=a.seconds(10);function _t(){setInterval(async()=>{if(!_e){_e=true;try{await kt();}catch(t){console.error("Error syncing status",t);}try{await Uo();}catch(t){console.error("Error syncing config",t);}_e=false;}},jo);}async function Uo(){let{configs:t}=await Dt();c(t);}var X=new w("_modelenceLocks",{schema:{resource:d.string(),instanceId:d.string(),acquiredAt:d.date()},indexes:[{key:{resource:1},unique:true},{key:{resource:1,instanceId:1}},{key:{resource:1,acquiredAt:1}}]});var Z={},At=a.seconds(10),Ot=randomBytes(32).toString("base64url"),No=a.seconds(30);async function ue(t,{lockDuration:e=No,successfulLockCacheDuration:o=At,failedLockCacheDuration:r=At,instanceId:n=Ot}={}){let i=Date.now();if(Z[t]&&i<Z[t].expiresAt)return Z[t].value;let s=new Date(i-e);h$1(`Attempting to acquire lock: ${t}`,{source:"lock",resource:t,instanceId:n});try{let a=await X.upsertOne({$or:[{resource:t,instanceId:n},{resource:t,acquiredAt:{$lt:s}}]},{$set:{resource:t,instanceId:n,acquiredAt:new Date}}),c=a.upsertedCount>0||a.modifiedCount>0;return Z[t]={value:c,expiresAt:i+(c?o:r)},c?h$1(`Lock acquired: ${t}`,{source:"lock",resource:t,instanceId:n}):h$1(`Failed to acquire lock (already held): ${t}`,{source:"lock",resource:t,instanceId:n}),c}catch{return Z[t]={value:false,expiresAt:i+r},h$1(`Failed to acquire lock (already held): ${t}`,{source:"lock",resource:t,instanceId:n}),false}}async function Rt(t,{instanceId:e=Ot}={}){let o=await X.deleteOne({resource:t,instanceId:e});return delete Z[t],o.deletedCount>0}var zo=a.minutes(1),$={},Ae=null,Oe=new w("_modelenceCronJobs",{schema:{alias:d.string(),lastStartDate:d.date().optional()},indexes:[{key:{alias:1},unique:true,background:true}]});function It(t,{description:e="",interval:o,timeout:r=zo,handler:n}){if($[t])throw new Error(`Duplicate cron job declaration: '${t}' already exists`);if(Ae)throw new Error(`Unable to add a cron job - cron jobs have already been initialized: [${t}]`);if(o<a.seconds(5))throw new Error(`Cron job interval should not be less than 5 second [${t}]`);if(r>a.days(1))throw new Error(`Cron job timeout should not be longer than 1 day [${t}]`);$[t]={alias:t,params:{description:e,interval:o,timeout:r},handler:n,state:{isRunning:false}};}async function Lt(){if(Ae)throw new Error("Cron jobs already started");let t=Object.keys($);if(t.length>0){let e={alias:{$in:t}},o=await Oe.fetch(e),r=Date.now();o.forEach(n=>{let i=$[n.alias];i&&(i.state.scheduledRunTs=n.lastStartDate?n.lastStartDate.getTime()+i.params.interval:r);}),Object.values($).forEach(n=>{n.state.scheduledRunTs||(n.state.scheduledRunTs=r);}),Ae=setInterval(Fo,a.seconds(1));}}async function Fo(){let t=Date.now();await ue("cron",{successfulLockCacheDuration:a.seconds(10),failedLockCacheDuration:a.seconds(30)})&&Object.values($).forEach(async o=>{let{params:r,state:n}=o;if(n.isRunning){n.startTs&&n.startTs+r.timeout<t&&(n.isRunning=false);return}n.scheduledRunTs&&n.scheduledRunTs<=t&&await qo(o);});}async function qo(t){let{alias:e,params:o,handler:r,state:n}=t;n.isRunning=true,n.startTs=Date.now(),await Oe.updateOne({alias:e},{$set:{lastStartDate:new Date(n.startTs)}});let i=k$1("cron",`cron:${e}`);try{await r(),Mt(n,o),i.end("success");}catch(s){Mt(n,o);let a=s instanceof Error?s:new Error(String(s));l(a),i.end("error"),console.error(`Error in cron job '${e}':`,s);}}function Mt(t,e){t.scheduledRunTs=t.startTs?t.startTs+e.interval:Date.now(),t.startTs=void 0,t.isRunning=false;}function Pt(){return Object.values($).map(({alias:t,params:e})=>({alias:t,description:e.description,interval:e.interval,timeout:e.timeout}))}var jt=new E("_system.cron",{stores:[Oe]});var Re=new E("_system.lock",{stores:[X]});var ee=new w("_modelenceMigrations",{schema:{version:d.number(),status:d.enum(["completed","failed"]),description:d.string().optional(),output:d.string().optional(),appliedAt:d.date()},indexes:[{key:{version:1},unique:true},{key:{version:1,status:1}}]});async function Wo(t){if(t.length===0)return;if(!await ue("migrations")){i("Another instance is running migrations. Skipping migration run.",{source:"migrations"});return}let o=t.map(({version:s})=>s),r=await ee.fetch({version:{$in:o}}),n=new Set(r.map(({version:s})=>s)),i$1=t.filter(({version:s})=>!n.has(s));if(i$1.length!==0){i(`Running migrations (${i$1.length})...`,{source:"migrations"});for(let{version:s,description:a,handler:c}of i$1){i(`Running migration v${s}: ${a}`,{source:"migrations"});try{let p=(await c()||"").toString().trim(),u=15*1024*1024,C=p.length>u?p.slice(0,u)+`
15
+ [Output truncated - exceeded size limit]`:p;await ee.upsertOne({version:s},{$set:{version:s,status:"completed",description:a,output:C,appliedAt:new Date}}),i(`Migration v${s} complete`,{source:"migrations"});}catch(l){l instanceof Error&&(await ee.upsertOne({version:s},{$set:{version:s,status:"failed",description:a,output:l.message||"",appliedAt:new Date}}),i(`Migration v${s} is failed: ${l.message}`,{source:"migrations"}));}}await Rt("migrations");}}function Ut(t){setTimeout(()=>{Wo(t).catch(e=>{console.error("Error running migrations:",e);});},0);}var $t=new E("_system.migration",{stores:[ee]});var Nt=new E("_system.rateLimit",{stores:[Y]});var zt=new E("_system",{configSchema:{mongodbUrl:{type:"string",isPublic:false,default:""},env:{type:"string",isPublic:true,default:""},"site.url":{type:"string",isPublic:true,default:""}}});var Ie=class{async init(){this.config=await Yo(),this.isDev()&&(console.log("Starting Vite dev server..."),this.viteServer=await createServer(this.config));}middlewares(){if(this.isDev())return this.viteServer?.middlewares??[];let e=[I.static("./.modelence/build/client".replace(/\\/g,"/"))];return this.config?.publicDir&&e.push(I.static(this.config.publicDir)),e}handler(e,o){if(this.isDev())try{o.sendFile("index.html",{root:"./src/client"});}catch(r){console.error("Error serving index.html:",r),o.status(500).send("Internal Server Error");}else o.sendFile("index.html",{root:"./.modelence/build/client".replace(/\\/g,"/")});}isDev(){return process.env.NODE_ENV!=="production"}};async function Ho(){let t=process.cwd();try{return (await loadConfigFromFile({command:"serve",mode:"development"},void 0,t))?.config||{}}catch(e){return console.warn("Could not load vite config:",e),{}}}function Ko(t,e){let o=mergeConfig(t,e);if(o.plugins&&Array.isArray(o.plugins)){let r=new Set;o.plugins=o.plugins.flat().filter(n=>{if(!n||typeof n!="object"||Array.isArray(n))return true;let i=n.name;return !i||r.has(i)?false:(r.add(i),true)}).reverse(),o.plugins.reverse();}return o}async function Yo(){let t=process.cwd(),e=await Ho(),o=[".eslintrc.js",".eslintrc.json",".eslintrc","eslint.config.js",".eslintrc.yml",".eslintrc.yaml"].find(i=>Go.existsSync(Me.join(t,i))),r=[Qo(),Xo()];if(o){let i=(await import('vite-plugin-eslint')).default;r.push(i({failOnError:false,include:["src/**/*.js","src/**/*.jsx","src/**/*.ts","src/**/*.tsx"],cwd:t,overrideConfigFile:Me.resolve(t,o)}));}let n=defineConfig({plugins:r,build:{outDir:".modelence/build/client".replace(/\\/g,"/"),emptyOutDir:true},server:{middlewareMode:true},root:"./src/client",resolve:{alias:{"@":Me.resolve(t,"src").replace(/\\/g,"/")}}});return Ko(n,e)}function Xo(){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}}}var qt=new Ie;async function Wt(t,e){let{authToken:o}=await ye(e);t.cookie("authToken",o,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"strict"}),t.status(301),t.redirect("/");}function B(t){return `${a$1("_system.site.url")}/api/_internal/auth/${t}/callback`}async function pe(t,e,o){let r=await f.findOne({[`authMethods.${o.providerName}.id`]:o.id}),{session:n,connectionInfo:i}=await Le(t);try{if(r){await Wt(e,r._id),h().onAfterLogin?.({provider:o.providerName,user:r,session:n,connectionInfo:i}),h().login?.onSuccess?.(r);return}}catch(s){throw s instanceof Error&&(h().login?.onError?.(s),h().onLoginError?.({provider:o.providerName,error:s,session:n,connectionInfo:i})),s}try{if(!o.email){e.status(400).json({error:`Email address is required for ${o.providerName} authentication.`});return}if(await f.findOne({"emails.address":o.email},{collation:{locale:"en",strength:2}})){e.status(400).json({error:"User with this email already exists. Please log in instead."});return}let a=await f.insertOne({handle:o.email,status:"active",emails:[{address:o.email,verified:o.emailVerified}],createdAt:new Date,authMethods:{[o.providerName]:{id:o.id}}});await Wt(e,a.insertedId);let c=await f.findOne({_id:a.insertedId},{readPreference:"primary"});c&&(h().onAfterSignup?.({provider:o.providerName,user:c,session:n,connectionInfo:i}),h().signup?.onSuccess?.(c));}catch(s){throw s instanceof Error&&(h().onSignupError?.({provider:o.providerName,error:s,session:n,connectionInfo:i}),h().signup?.onError?.(s)),s}}function me(t){return !t||typeof t!="string"?null:t}async function or(t,e,o,r){let n=await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code:t,client_id:e,client_secret:o,redirect_uri:r,grant_type:"authorization_code"})});if(!n.ok)throw new Error(`Failed to exchange code for token: ${n.statusText}`);return n.json()}async function rr(t){let e=await fetch("https://www.googleapis.com/oauth2/v2/userinfo",{headers:{Authorization:`Bearer ${t}`}});if(!e.ok)throw new Error(`Failed to fetch user info: ${e.statusText}`);return e.json()}async function nr(t,e){let o=me(t.query.code),r=t.query.state,n=t.cookies.authStateGoogle;if(!o){e.status(400).json({error:"Missing authorization code"});return}if(!r||!n||r!==n){e.status(400).json({error:"Invalid OAuth state - possible CSRF attack"});return}e.clearCookie("authStateGoogle");let i=String(a$1("_system.user.auth.google.clientId")),s=String(a$1("_system.user.auth.google.clientSecret")),a=B("google");try{let c=await or(o,i,s,a),l=await rr(c.access_token),p={id:l.id,email:l.email,emailVerified:l.verified_email,providerName:"google"};await pe(t,e,p);}catch(c){console.error("Google OAuth error:",c),e.status(500).json({error:"Authentication failed"});}}function ir(){let t=Router(),e=(o,r,n)=>{let i=!!a$1("_system.user.auth.google.enabled"),s=String(a$1("_system.user.auth.google.clientId")),a=String(a$1("_system.user.auth.google.clientSecret"));if(!i||!s||!a){r.status(503).json({error:"Google authentication is not configured"});return}n();};return t.get("/api/_internal/auth/google",e,(o,r)=>{let n=String(a$1("_system.user.auth.google.clientId")),i=B("google"),s=randomBytes(32).toString("hex");r.cookie("authStateGoogle",s,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"lax",maxAge:a.minutes(10)});let a$2=new URL("https://accounts.google.com/o/oauth2/v2/auth");a$2.searchParams.append("client_id",n),a$2.searchParams.append("redirect_uri",i),a$2.searchParams.append("response_type","code"),a$2.searchParams.append("scope","profile email"),a$2.searchParams.append("access_type","online"),a$2.searchParams.append("state",s),r.redirect(a$2.toString());}),t.get("/api/_internal/auth/google/callback",e,nr),t}var Zt=ir;async function cr(t,e,o,r){let n=await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({client_id:e,client_secret:o,code:t,redirect_uri:r})});if(!n.ok)throw new Error(`Failed to exchange code for token: ${n.statusText}`);return n.json()}async function lr(t){let e=await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${t}`,Accept:"application/vnd.github.v3+json"}});if(!e.ok)throw new Error(`Failed to fetch user info: ${e.statusText}`);return e.json()}async function dr(t,e){let o=me(t.query.code),r=t.query.state,n=t.cookies.authStateGithub;if(!o){e.status(400).json({error:"Missing authorization code"});return}if(!r||!n||r!==n){e.status(400).json({error:"Invalid OAuth state - possible CSRF attack"});return}e.clearCookie("authStateGithub");let i=String(a$1("_system.user.auth.github.clientId")),s=String(a$1("_system.user.auth.github.clientSecret")),a=B("github");try{let c=await cr(o,i,s,a),l=await lr(c.access_token),p=l.email||"";if(!p){e.status(400).json({error:"Unable to retrieve email from GitHub. Please ensure your email is public or grant email permissions."});return}let u={id:String(l.id),email:p,emailVerified:!0,providerName:"github"};await pe(t,e,u);}catch(c){console.error("GitHub OAuth error:",c),e.status(500).json({error:"Authentication failed"});}}function ur(){let t=Router(),e=(o,r,n)=>{let i=!!a$1("_system.user.auth.github.enabled"),s=String(a$1("_system.user.auth.github.clientId")),a=String(a$1("_system.user.auth.github.clientSecret"));if(!i||!s||!a){r.status(503).json({error:"GitHub authentication is not configured"});return}n();};return t.get("/api/_internal/auth/github",e,(o,r)=>{let n=String(a$1("_system.user.auth.github.clientId")),i=B("github"),s=a$1("_system.user.auth.github.scopes"),a$2=s?String(s).split(",").map(p=>p.trim()).join(" "):"user:email",c=randomBytes(32).toString("hex");r.cookie("authStateGithub",c,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"lax",maxAge:a.minutes(10)});let l=new URL("https://github.com/login/oauth/authorize");l.searchParams.append("client_id",n),l.searchParams.append("redirect_uri",i),l.searchParams.append("scope",a$2),l.searchParams.append("state",c),r.redirect(l.toString());}),t.get("/api/_internal/auth/github/callback",e,dr),t}var Bt=ur;function Vt(t,e,o){return async(r,n,i)=>{let s=r.headers["x-modelence-auth-token"],a={session:null,user:null};if(typeof s=="string"&&j())try{let{session:l,user:p}=await T(s);a={session:l,user:p};}catch{}let c=k$1("route",`route:${t.toLowerCase()}:${e}`,{method:t,path:e,query:r.query,body:r.body,params:r.params});try{let l=await o({query:r.query,body:r.body,params:r.params,headers:r.headers,cookies:r.cookies,rawBody:Buffer.isBuffer(r.body)?r.body:void 0,req:r,res:n,next:i},a);c.end(),l&&(n.status(l.status||200),l.redirect&&n.redirect(l.redirect),l.headers&&Object.entries(l.headers).forEach(([p,u])=>{n.setHeader(p,u);}),n.send(l.data));}catch(l){c.end("error"),l instanceof a$3?n.status(l.status).send(l.message):(console.error(`Error in route handler: ${r.path}`),console.error(l),n.status(500).send(String(l)));}}}var Pe=Object.freeze({});function Jt(t){Pe=Object.freeze(Object.assign({},Pe,t));}function fe(){return Pe}function fr(t){let e=[];if(!t)return e.push(I.json({limit:"16mb"})),e.push(I.urlencoded({extended:true,limit:"16mb"})),e;if(t.json!==false){let o=typeof t.json=="object"?t.json:{limit:"16mb"};e.push(I.json(o));}if(t.urlencoded!==false){let o=typeof t.urlencoded=="object"?t.urlencoded:{extended:true,limit:"16mb"};e.push(I.urlencoded(o));}if(t.raw){let o=typeof t.raw=="object"?t.raw:{},r={limit:o.limit||"16mb",type:o.type||"*/*"};e.push(I.raw(r));}return e}function hr(t,e){for(let o of e)for(let r of o.routes){let{path:n,handlers:i,body:s}=r,a=fr(s);Object.entries(i).forEach(([c,l])=>{t[c](n,...a,Vt(c,n,l));});}}async function Qt(t,{combinedModules:e,channels:o}){let r=I();r.use(pr()),hr(r,e),r.use(I.json({limit:"16mb"})),r.use(I.urlencoded({extended:true,limit:"16mb"})),r.use(Zt()),r.use(Bt()),r.post("/api/_internal/method/:methodName(*)",async(a,c)=>{let{methodName:l}=a.params,p=await Le(a);try{let u=await st(l,a.body.args,p);c.json({data:u,typeMap:a$2(u)});}catch(u){gr(c,l,u);}}),await t.init(),t.middlewares&&r.use(t.middlewares()),r.all("*",(a,c)=>t.handler(a,c)),process.on("unhandledRejection",(a,c)=>{console.error("Unhandled Promise Rejection:"),console.error(a instanceof Error?a.stack:a),console.error("Promise:",c);}),process.on("uncaughtException",a=>{console.error("Uncaught Exception:"),console.error(a.stack),console.trace("Full application stack:");});let n=mr.createServer(r),i$1=fe()?.provider;i$1&&i$1.init({httpServer:n,channels:o});let s=process.env.MODELENCE_PORT||process.env.PORT||3e3;n.listen(s,()=>{i("Application started",{source:"app"});let a=process.env.MODELENCE_SITE_URL||`http://localhost:${s}`;console.log(`
16
16
  Application started on ${a}
17
- `);});}async function Ie(t){let e=R.string().nullish().transform(i=>i??null).parse(t.cookies.authToken||t.body.authToken),o=R.object({screenWidth:R.number(),screenHeight:R.number(),windowWidth:R.number(),windowHeight:R.number(),pixelRatio:R.number(),orientation:R.string().nullable()}).nullish().parse(t.body.clientInfo)??{screenWidth:0,screenHeight:0,windowWidth:0,windowHeight:0,pixelRatio:1,orientation:null},r={ip:yr(t),userAgent:t.get("user-agent"),acceptLanguage:t.get("accept-language"),referrer:t.get("referrer"),baseUrl:t.protocol+"://"+t.get("host")};if(!!P()){let{session:i,user:s,roles:a}=await k(e);return {clientInfo:o,connectionInfo:r,session:i,user:s,roles:a}}return {clientInfo:o,connectionInfo:r,session:null,user:null,roles:oe()}}function gr(t,e,o){try{if(o instanceof Error&&o?.constructor?.name==="ZodError"&&"errors"in o){let n=o.flatten(),i=Object.entries(n.fieldErrors).map(([c,l])=>`${c}: ${(l??[]).join(", ")}`).join("; "),s=n.formErrors.join("; "),a=[i,s].filter(Boolean).join("; ");console.error(`Error in method ${e}: ZodError - ${a}`);}else o instanceof Error?(console.error(`Error in method ${e}:`,o.message),o.stack&&console.error(o.stack)):console.error(`Error in method ${e}:`,String(o));}catch{console.error(`Error in method ${e}: [Failed to log error details]`);}if(o instanceof a$3)t.status(o.status).send(o.message);else if(o instanceof Error&&o?.constructor?.name==="ZodError"&&"errors"in o){let n=o.flatten(),i=Object.entries(n.fieldErrors).map(([c,l])=>`${c}: ${(l??[]).join(", ")}`).join("; "),s=n.formErrors.join("; "),a=[i,s].filter(Boolean).join("; ");t.status(400).send(a);}else t.status(500).send(o instanceof Error?o.message:String(o));}function yr(t){let e=t.headers["x-forwarded-for"];if(e)return (Array.isArray(e)?e[0]:e.split(",")[0]).trim();let o=t.ip||t.socket?.remoteAddress;if(o)return o.startsWith("::ffff:")?o.substring(7):o}async function Sr({modules:t=[],roles:e$1={},defaultRoles:o={},server:r=qt,migrations:n=[],email:i={},auth:s={},websocket:a={}}){Qt.config(),Qt.config({path:".modelence.env"});let c$1=!!process.env.MODELENCE_SERVICE_ENDPOINT,l=process.env.MODELENCE_CRON_ENABLED==="true";Ir().then(()=>{}).catch(()=>{});let f$1=[vt,He,Ut,$t,Nt,zt,Oe],m=[...f$1,...t];e(),xr(f$1),Cr(t),Ye(e$1,o);let S=_r(m);d$2(S);let x=vr(m),I=Tr(m);l&&kr(m);let C=Dr(m);if(Et(C),c$1){let{configs:me,environmentId:Kt,appAlias:Yt,environmentAlias:Xt,telemetry:eo}=await Tt({configSchema:S,cronJobsMetadata:l?Pt():void 0,stores:x});c(me),f({environmentId:Kt,appAlias:Yt,environmentAlias:Xt,telemetry:eo});}else c(Mr(S));ut(i),mt(s),Jt({...a,provider:a.provider||ct});let Ue=P();if(Ue&&(await et(),Ar(x)),l&&jt(n),Ue)for(let me of x)me.createIndexes();c$1&&(await g(),kt()),l&&Lt().catch(console.error),await Gt(r,{combinedModules:m,channels:I});}function Cr(t){for(let e of t){for(let[o,r]of Object.entries(e.queries))we(`${e.name}.${o}`,r);for(let[o,r]of Object.entries(e.mutations))tt(`${e.name}.${o}`,r);}}function xr(t){for(let e of t){for(let[o,r]of Object.entries(e.queries))ot(`${e.name}.${o}`,r);for(let[o,r]of Object.entries(e.mutations))rt(`${e.name}.${o}`,r);}}function vr(t){return t.flatMap(e=>e.stores)}function Tr(t){return t.flatMap(e=>e.channels)}function Dr(t){return t.flatMap(e=>e.rateLimits)}function _r(t){let e={};for(let o of t)for(let[r,n]of Object.entries(o.configSchema)){let i=`${o.name}.${r}`;if(i in e)throw new Error(`Duplicate config schema key: ${i} (${o.name})`);e[i]=n;}return e}function kr(t){for(let e of t)for(let[o,r]of Object.entries(e.cronJobs))It(`${e.name}.${o}`,r);}function Ar(t){let e=re();if(!e)throw new Error("Failed to initialize stores: MongoDB client not initialized");for(let o of t)o.init(e);}var Or={MONGODB_URI:"_system.mongodbUri",MODELENCE_AUTH_GOOGLE_ENABLED:"_system.user.auth.google.enabled",MODELENCE_AUTH_GOOGLE_CLIENT_ID:"_system.user.auth.google.clientId",MODELENCE_AUTH_GOOGLE_CLIENT_SECRET:"_system.user.auth.google.clientSecret",MODELENCE_AUTH_GITHUB_ENABLED:"_system.user.auth.github.enabled",MODELENCE_AUTH_GITHUB_CLIENT_ID:"_system.user.auth.github.clientId",MODELENCE_AUTH_GITHUB_CLIENT_SECRET:"_system.user.auth.github.clientSecret",MODELENCE_AUTH_GITHUB_CLIENT_SCOPES:"_system.user.auth.github.scopes",MODELENCE_EMAIL_RESEND_API_KEY:"_system.email.resend.apiKey",MODELENCE_EMAIL_AWS_SES_REGION:"_system.email.awsSes.region",MODELENCE_EMAIL_AWS_SES_ACCESS_KEY_ID:"_system.email.awsSes.accessKeyId",MODELENCE_EMAIL_AWS_SES_SECRET_ACCESS_KEY:"_system.email.awsSes.secretAccessKey",MODELENCE_EMAIL_SMTP_HOST:"_system.email.smtp.host",MODELENCE_EMAIL_SMTP_PORT:"_system.email.smtp.port",MODELENCE_EMAIL_SMTP_USER:"_system.email.smtp.user",MODELENCE_EMAIL_SMTP_PASS:"_system.email.smtp.pass",MODELENCE_SITE_URL:"_system.site.url",MODELENCE_ENV:"_system.env",GOOGLE_AUTH_ENABLED:"_system.user.auth.google.enabled",GOOGLE_AUTH_CLIENT_ID:"_system.user.auth.google.clientId",GOOGLE_AUTH_CLIENT_SECRET:"_system.user.auth.google.clientSecret"};function Rr(t,e){if(e==="number"){let o=Number(t);if(isNaN(o))throw new Error(`Invalid number value for config: ${t}`);return o}if(e==="boolean"){if(t.toLowerCase()==="true")return true;if(t.toLowerCase()==="false")return false;throw new Error(`Invalid boolean value for config: ${t}`)}return t}function Mr(t){let e=[];for(let[o,r]of Object.entries(Or)){let n=process.env[o],i=t[r];if(n){let s=i?.type??"string";e.push({key:r,type:s,value:Rr(n,s)});}}return e}async function Ir(){if(process.env.MODELENCE_TRACKING_ENABLED!=="false"){let e=process.env.MODELENCE_SERVICE_ENDPOINT??"https://cloud.modelence.com",o=process.env.MODELENCE_ENVIRONMENT_ID,r=await Lr(),n=await import('./package-EO7F6GC2.js');await fetch(`${e}/api/track/app-start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:r.name,version:n.default.version,localHostname:Po.hostname(),environmentId:o})});}}async function Lr(){try{let t=Re.join(process.cwd(),"package.json"),e=await wr.readFile(t,"utf-8");return {name:JSON.parse(e).name||"unknown"}}catch{return {name:"unknown"}}}async function Ht(t){await _.deleteMany({userId:t}),await v.deleteMany({userId:t});}async function Ur(t){await Ht(t),await p.updateOne(t,{$set:{status:"disabled",disabledAt:new Date}});}async function jr(t){await Ht(t),await p.updateOne({_id:t},{$set:{handle:`deleted-${t}-${randomUUID()}`,status:"deleted",deletedAt:new Date,authMethods:{},emails:[]}});}var Pe=class{constructor(e,o){this.category=e,this.canAccessChannel=o||null;}broadcast(e,o){let r=pe().provider;if(!r){j$1("Websockets provider should be added to startApp",{});return}r.broadcast({category:this.category,id:e,data:o});}};function $r(t){if(!b().provider)throw new Error("Email provider is not configured, see https://docs.modelence.com/email for more details.");return b().provider?.sendEmail(t)}
18
- export{F as LiveData,E as Module,Pe as ServerChannel,w as Store,k as authenticate,j as consumeRateLimit,we as createQuery,p as dbUsers,jr as deleteUser,Ur as disableUser,d as schema,$r as sendEmail,Sr as startApp};//# sourceMappingURL=server.js.map
17
+ `);});}async function Le(t){let e=M.string().nullish().transform(i=>i??null).parse(t.cookies.authToken||t.body.authToken),o=M.object({screenWidth:M.number(),screenHeight:M.number(),windowWidth:M.number(),windowHeight:M.number(),pixelRatio:M.number(),orientation:M.string().nullable()}).nullish().parse(t.body.clientInfo)??{screenWidth:0,screenHeight:0,windowWidth:0,windowHeight:0,pixelRatio:1,orientation:null},r={ip:yr(t),userAgent:t.get("user-agent"),acceptLanguage:t.get("accept-language"),referrer:t.get("referrer"),baseUrl:t.protocol+"://"+t.get("host")};if(!!j()){let{session:i,user:s,roles:a}=await T(e);return {clientInfo:o,connectionInfo:r,session:i,user:s,roles:a}}return {clientInfo:o,connectionInfo:r,session:null,user:null,roles:ne()}}function gr(t,e,o){try{if(o instanceof Error&&o?.constructor?.name==="ZodError"&&"errors"in o){let n=o.flatten(),i=Object.entries(n.fieldErrors).map(([c,l])=>`${c}: ${(l??[]).join(", ")}`).join("; "),s=n.formErrors.join("; "),a=[i,s].filter(Boolean).join("; ");console.error(`Error in method ${e}: ZodError - ${a}`);}else o instanceof Error?(console.error(`Error in method ${e}:`,o.message),o.stack&&console.error(o.stack)):console.error(`Error in method ${e}:`,String(o));}catch{console.error(`Error in method ${e}: [Failed to log error details]`);}if(o instanceof a$3)t.status(o.status).send(o.message);else if(o instanceof Error&&o?.constructor?.name==="ZodError"&&"errors"in o){let n=o.flatten(),i=Object.entries(n.fieldErrors).map(([c,l])=>`${c}: ${(l??[]).join(", ")}`).join("; "),s=n.formErrors.join("; "),a=[i,s].filter(Boolean).join("; ");t.status(400).send(a);}else t.status(500).send(o instanceof Error?o.message:String(o));}function yr(t){let e=t.headers["x-forwarded-for"];if(e)return (Array.isArray(e)?e[0]:e.split(",")[0]).trim();let o=t.ip||t.socket?.remoteAddress;if(o)return o.startsWith("::ffff:")?o.substring(7):o}async function Sr({modules:t=[],roles:e$1={},defaultRoles:o={},server:r=qt,migrations:n=[],email:i={},auth:s={},websocket:a={}}){Gt.config(),Gt.config({path:".modelence.env"});let c$1=!!process.env.MODELENCE_SERVICE_ENDPOINT,l=process.env.MODELENCE_CRON_ENABLED==="true";Ir().then(()=>{}).catch(()=>{});let p=[vt,He,jt,$t,Nt,zt,Re],u=[...p,...t];e(),xr(p),Cr(t),Ye(e$1,o);let C=kr(u);d$2(C);let x=vr(u),L=Tr(u);l&&_r(u);let V=Dr(u);if(Et(V),c$1){let{configs:S,environmentId:Kt,appAlias:Yt,environmentAlias:Xt,telemetry:eo}=await Tt({configSchema:C,cronJobsMetadata:l?Pt():void 0,stores:x});c(S),f$1({environmentId:Kt,appAlias:Yt,environmentAlias:Xt,telemetry:eo});}else c(Mr(C));ut(i),mt(s),Jt({...a,provider:a.provider||ct});let N=j();if(N&&(await et(),Ar(x)),l&&Ut(n),N)for(let S of x)S.createIndexes();c$1&&(await g(),_t()),l&&Lt().catch(console.error),await Qt(r,{combinedModules:u,channels:L});}function Cr(t){for(let e of t){for(let[o,r]of Object.entries(e.queries))be(`${e.name}.${o}`,r);for(let[o,r]of Object.entries(e.mutations))tt(`${e.name}.${o}`,r);}}function xr(t){for(let e of t){for(let[o,r]of Object.entries(e.queries))ot(`${e.name}.${o}`,r);for(let[o,r]of Object.entries(e.mutations))rt(`${e.name}.${o}`,r);}}function vr(t){return t.flatMap(e=>e.stores)}function Tr(t){return t.flatMap(e=>e.channels)}function Dr(t){return t.flatMap(e=>e.rateLimits)}function kr(t){let e={};for(let o of t)for(let[r,n]of Object.entries(o.configSchema)){let i=`${o.name}.${r}`;if(i in e)throw new Error(`Duplicate config schema key: ${i} (${o.name})`);e[i]=n;}return e}function _r(t){for(let e of t)for(let[o,r]of Object.entries(e.cronJobs))It(`${e.name}.${o}`,r);}function Ar(t){let e=ie();if(!e)throw new Error("Failed to initialize stores: MongoDB client not initialized");for(let o of t)o.init(e);}var Or={MONGODB_URI:"_system.mongodbUri",MODELENCE_AUTH_GOOGLE_ENABLED:"_system.user.auth.google.enabled",MODELENCE_AUTH_GOOGLE_CLIENT_ID:"_system.user.auth.google.clientId",MODELENCE_AUTH_GOOGLE_CLIENT_SECRET:"_system.user.auth.google.clientSecret",MODELENCE_AUTH_GITHUB_ENABLED:"_system.user.auth.github.enabled",MODELENCE_AUTH_GITHUB_CLIENT_ID:"_system.user.auth.github.clientId",MODELENCE_AUTH_GITHUB_CLIENT_SECRET:"_system.user.auth.github.clientSecret",MODELENCE_AUTH_GITHUB_CLIENT_SCOPES:"_system.user.auth.github.scopes",MODELENCE_EMAIL_RESEND_API_KEY:"_system.email.resend.apiKey",MODELENCE_EMAIL_AWS_SES_REGION:"_system.email.awsSes.region",MODELENCE_EMAIL_AWS_SES_ACCESS_KEY_ID:"_system.email.awsSes.accessKeyId",MODELENCE_EMAIL_AWS_SES_SECRET_ACCESS_KEY:"_system.email.awsSes.secretAccessKey",MODELENCE_EMAIL_SMTP_HOST:"_system.email.smtp.host",MODELENCE_EMAIL_SMTP_PORT:"_system.email.smtp.port",MODELENCE_EMAIL_SMTP_USER:"_system.email.smtp.user",MODELENCE_EMAIL_SMTP_PASS:"_system.email.smtp.pass",MODELENCE_SITE_URL:"_system.site.url",MODELENCE_ENV:"_system.env",GOOGLE_AUTH_ENABLED:"_system.user.auth.google.enabled",GOOGLE_AUTH_CLIENT_ID:"_system.user.auth.google.clientId",GOOGLE_AUTH_CLIENT_SECRET:"_system.user.auth.google.clientSecret"};function Rr(t,e){if(e==="number"){let o=Number(t);if(isNaN(o))throw new Error(`Invalid number value for config: ${t}`);return o}if(e==="boolean"){if(t.toLowerCase()==="true")return true;if(t.toLowerCase()==="false")return false;throw new Error(`Invalid boolean value for config: ${t}`)}return t}function Mr(t){let e=[];for(let[o,r]of Object.entries(Or)){let n=process.env[o],i=t[r];if(n){let s=i?.type??"string";e.push({key:r,type:s,value:Rr(n,s)});}}return e}async function Ir(){if(process.env.MODELENCE_TRACKING_ENABLED!=="false"){let e=process.env.MODELENCE_SERVICE_ENDPOINT??"https://cloud.modelence.com",o=process.env.MODELENCE_ENVIRONMENT_ID,r=await Lr(),n=await import('./package-Y3SS4LHP.js');await fetch(`${e}/api/track/app-start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:r.name,version:n.default.version,localHostname:Po.hostname(),environmentId:o})});}}async function Lr(){try{let t=Me.join(process.cwd(),"package.json"),e=await wr.readFile(t,"utf-8");return {name:JSON.parse(e).name||"unknown"}}catch{return {name:"unknown"}}}async function Ht(t){await _.deleteMany({userId:t}),await v.deleteMany({userId:t});}async function jr(t){await Ht(t),await f.updateOne(t,{$set:{status:"disabled",disabledAt:new Date}});}async function Ur(t){await Ht(t),await f.updateOne({_id:t},{$set:{handle:`deleted-${t}-${randomUUID()}`,status:"deleted",deletedAt:new Date,authMethods:{},emails:[]}});}var je=class{constructor(e,o){this.category=e,this.canAccessChannel=o||null;}broadcast(e,o){let r=fe().provider;if(!r){j$1("Websockets provider should be added to startApp",{});return}r.broadcast({category:this.category,id:e,data:o});}};function $r(t){if(!b().provider)throw new Error("Email provider is not configured, see https://docs.modelence.com/email for more details.");return b().provider?.sendEmail(t)}
18
+ export{q as LiveData,E as Module,je as ServerChannel,w as Store,T as authenticate,U as consumeRateLimit,be as createQuery,f as dbUsers,Ur as deleteUser,jr as disableUser,d as schema,$r as sendEmail,Sr as startApp};//# sourceMappingURL=server.js.map
19
19
  //# sourceMappingURL=server.js.map