modelence 0.6.6-dev.0 → 0.6.7

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.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { A as AppServer } from './index-CwdohC5n.js';
2
- import { P as Permission, S as Session, U as UserInfo, C as ConfigSchema, d as ServerChannel, e as User, W as WebsocketServerProvider, R as RoleDefinition, b as ConfigKey, A as AppConfig, f as Role } from './types-B8cRKzII.js';
3
- import { ObjectId as ObjectId$1, WithId, IndexDescription, SearchIndexDescription, MongoClient, Collection, Filter, FindOptions, Document, OptionalUnlessRequiredId, InsertOneResult, InsertManyResult, UpdateFilter, UpdateResult, ClientSession, DeleteResult, AggregateOptions, AggregationCursor, AnyBulkWriteOperation, BulkWriteResult, Db } from 'mongodb';
2
+ import { P as Permission, S as Session, U as UserInfo, C as ConfigSchema, d as ServerChannel, e as User, W as WebsocketServerProvider, R as RoleDefinition, b as ConfigKey, A as AppConfig, f as Role } from './types-CZnqkmY_.js';
3
+ import * as mongodb from 'mongodb';
4
+ import { ObjectId as ObjectId$1, WithId, IndexDescription, SearchIndexDescription, MongoClient, Collection, Filter, FindOptions, Document, OptionalUnlessRequiredId, InsertOneResult, InsertManyResult, UpdateFilter, UpdateResult, ClientSession, DeleteResult, AggregateOptions, AggregationCursor, AnyBulkWriteOperation, BulkWriteResult } from 'mongodb';
4
5
  export { ObjectId } from 'mongodb';
5
6
  import * as zod from 'zod';
6
7
  import { z, ZodNumber, ZodArray } from 'zod';
7
- import { Request } from 'express';
8
+ import { Request, Response, NextFunction } from 'express';
8
9
  import { EmailProvider, EmailPayload } from './types.js';
9
10
  import 'http';
10
11
 
@@ -25,9 +26,9 @@ type ModelSchema = {
25
26
  [key: string]: SchemaTypeDefinition;
26
27
  };
27
28
  type InferDocumentType<T extends SchemaTypeDefinition> = {
28
- [K in keyof T as T[K] extends z.ZodOptional<any> ? K : never]?: (T[K] extends z.ZodType ? z.infer<T[K]> : never);
29
+ [K in keyof T as T[K] extends z.ZodOptional<z.ZodTypeAny> ? K : never]?: T[K] extends z.ZodType ? z.infer<T[K]> : never;
29
30
  } & {
30
- [K in keyof T as T[K] extends z.ZodOptional<any> ? never : K]: T[K] extends z.ZodType ? z.infer<T[K]> : T[K] extends Array<infer ElementType extends SchemaTypeDefinition> ? Array<InferDocumentType<ElementType>> : T[K] extends ObjectTypeDefinition ? InferDocumentType<T[K]> : never;
31
+ [K in keyof T as T[K] extends z.ZodOptional<z.ZodTypeAny> ? never : K]: T[K] extends z.ZodType ? z.infer<T[K]> : T[K] extends Array<infer ElementType extends SchemaTypeDefinition> ? Array<InferDocumentType<ElementType>> : T[K] extends ObjectTypeDefinition ? InferDocumentType<T[K]> : never;
31
32
  };
32
33
  declare const schema: {
33
34
  readonly string: (params?: z.RawCreateParams & {
@@ -51,9 +52,9 @@ declare const schema: {
51
52
  readonly embedding: () => ZodArray<ZodNumber>;
52
53
  readonly objectId: () => z.ZodType<ObjectId$1>;
53
54
  readonly userId: () => z.ZodType<ObjectId$1>;
54
- readonly ref: (collection: string | Store<any, any>) => z.ZodType<ObjectId$1>;
55
+ readonly ref: <T extends ModelSchema>(_collection: string | Store<T, InferDocumentType<T>>) => z.ZodType<ObjectId$1>;
55
56
  readonly union: <Options extends Readonly<[z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]>>(types: Options, params?: z.RawCreateParams) => z.ZodUnion<Options>;
56
- readonly infer: <T extends SchemaTypeDefinition>(schema: T) => InferDocumentType<T>;
57
+ readonly infer: <T extends SchemaTypeDefinition>(_schema: T) => InferDocumentType<T>;
57
58
  };
58
59
  declare namespace schema {
59
60
  type infer<T extends SchemaTypeDefinition> = InferDocumentType<T>;
@@ -83,7 +84,7 @@ declare namespace schema {
83
84
  * });
84
85
  * ```
85
86
  */
86
- declare class Store<TSchema extends ModelSchema, TMethods extends Record<string, (this: WithId<InferDocumentType<TSchema>> & TMethods, ...args: Parameters<any>) => any>> {
87
+ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string, (this: WithId<InferDocumentType<TSchema>> & TMethods, ...args: any[]) => any>> {
87
88
  /** @internal */
88
89
  readonly _type: InferDocumentType<TSchema>;
89
90
  /** @internal */
@@ -124,7 +125,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
124
125
  private wrapDocument;
125
126
  /**
126
127
  * For convenience, to also allow directy passing a string or ObjectId as the selector
127
- */
128
+ */
128
129
  private getSelector;
129
130
  /** @internal */
130
131
  requireCollection(): Collection<this["_type"]>;
@@ -249,7 +250,7 @@ declare class Store<TSchema extends ModelSchema, TMethods extends Record<string,
249
250
  * @returns The MongoDB database instance
250
251
  * @throws Error if the store is not provisioned
251
252
  */
252
- getDatabase(): Db;
253
+ getDatabase(): mongodb.Db;
253
254
  /**
254
255
  * Returns the raw MongoDB collection instance for advanced operations
255
256
  * @returns The MongoDB collection instance
@@ -365,28 +366,30 @@ type Context = {
365
366
  connectionInfo: ConnectionInfo;
366
367
  };
367
368
  type Args = Record<string, unknown>;
368
- type Handler<T extends any> = (args: Args, context: Context) => Promise<T> | T;
369
- type MethodDefinition<T extends any> = {
369
+ type Handler<T = unknown> = (args: Args, context: Context) => Promise<T> | T;
370
+ type MethodDefinition<T = unknown> = {
370
371
  permissions?: Permission[];
371
372
  handler: Handler<T>;
372
373
  } | Handler<T>;
373
374
 
374
375
  type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head' | 'all' | 'use';
375
- type RouteParams = {
376
+ type RouteParams<T = unknown> = {
376
377
  query: Record<string, string>;
377
- body: any;
378
+ body: T;
378
379
  params: Record<string, string>;
379
380
  headers: Record<string, string>;
380
381
  cookies: Record<string, string>;
381
382
  req: Request;
383
+ res: Response;
384
+ next: NextFunction;
382
385
  };
383
- type RouteResponse<T = any> = {
386
+ type RouteResponse<T = unknown> = {
384
387
  data?: T;
385
388
  status?: number;
386
389
  headers?: Record<string, string>;
387
390
  redirect?: string;
388
- };
389
- type RouteHandler<T = any> = (params: RouteParams) => Promise<RouteResponse<T>> | RouteResponse<T>;
391
+ } | null;
392
+ type RouteHandler<T = unknown> = (params: RouteParams) => Promise<RouteResponse<T>> | RouteResponse<T>;
390
393
  type RouteHandlers = {
391
394
  [key in HttpMethod]?: RouteHandler;
392
395
  };
@@ -465,7 +468,7 @@ declare class Module {
465
468
  *
466
469
  * @param options - Module configuration options
467
470
  */
468
- constructor(name: string, { stores, queries, mutations, routes, cronJobs, configSchema, rateLimits, channels }: {
471
+ constructor(name: string, { stores, queries, mutations, routes, cronJobs, configSchema, rateLimits, channels, }: {
469
472
  stores?: Store<any, any>[];
470
473
  queries?: Queries;
471
474
  mutations?: Mutations;
@@ -587,7 +590,7 @@ type AppOptions = {
587
590
  };
588
591
  declare function startApp({ modules, roles, defaultRoles, server, migrations, email, auth, websocket, }: AppOptions): Promise<void>;
589
592
 
590
- declare function createQuery<T extends any[]>(name: string, methodDef: MethodDefinition<T>): void;
593
+ declare function createQuery<T extends unknown[]>(name: string, methodDef: MethodDefinition<T>): void;
591
594
 
592
595
  /** @public */
593
596
  declare abstract class BSONValue {
@@ -853,7 +856,7 @@ declare const usersCollection: Store<{
853
856
  }>;
854
857
  }>, "handle" | "createdAt" | "emails" | "authMethods"> & {
855
858
  _id: ObjectId;
856
- }, ...args: Parameters<any>) => any>>;
859
+ }, ...args: any[]) => any>>;
857
860
 
858
861
  /**
859
862
  * This function will check all rate limit rules on the specified bucket and type,
package/dist/server.js CHANGED
@@ -1,18 +1,18 @@
1
- import {a as a$2}from'./chunk-DN5SVAO2.js';import {d,a as a$3}from'./chunk-C3UESBRX.js';import {a}from'./chunk-R7MPLJMA.js';import {b,e,d as d$1,c as c$1,f,g as g$1,i,a as a$1,h,j as j$1,k as k$1}from'./chunk-2QLNYYBR.js';export{a as getConfig}from'./chunk-2QLNYYBR.js';import Mt from'dotenv';import Wo from'fs/promises';import mo from'os';import fe 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}from'crypto';import x,{z as z$1}from'zod';import to from'bcrypt';import {createServer,defineConfig,loadConfigFromFile,mergeConfig}from'vite';import vo from'@vitejs/plugin-react';import _o from'fs';import be,{Router}from'express';import ge from'passport';import {Strategy}from'passport-google-oauth20';import {Strategy as Strategy$1}from'passport-github2';import $o from'cookie-parser';import No from'http';var w=class{constructor(e,{stores:o=[],queries:n={},mutations:r={},routes:i=[],cronJobs:s={},configSchema:a={},rateLimits:l=[],channels:d=[]}){this.name=e,this.stores=o,this.queries=n,this.mutations=r,this.routes=i,this.cronJobs=s,this.configSchema=a,this.rateLimits=l,this.channels=d;}};var y=class{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}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===68&&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 n=await this.requireCollection().findOne(e,o);return n?this.wrapDocument(n):null}async requireOne(e,o,n){let r=await this.findOne(e,o);if(!r)throw n?n():new Error(`Record not found in ${this.name}`);return r}find(e,o){let n=this.requireCollection().find(e);return o?.sort&&n.sort(o.sort),o?.limit&&n.limit(o.limit),o?.skip&&n.skip(o.skip),n}async findById(e){let o=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(o)}async requireById(e,o){let n=await this.findById(e);if(!n)throw o?o():new Error(`Record with id ${e} not found in ${this.name}`);return n}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,n){return await this.requireCollection().updateMany(e,o,n)}async upsertMany(e,o){return await this.requireCollection().updateMany(e,o,{upsert:true})}async deleteOne(e){return await this.requireCollection().deleteOne(e)}async deleteMany(e){return await this.requireCollection().deleteMany(e)}aggregate(e,o){return this.requireCollection().aggregate(e,o)}bulkWrite(e){return this.requireCollection().bulkWrite(e)}getDatabase(){return this.requireClient().db()}rawCollection(){return this.requireCollection()}async renameFrom(e,o){let n=this.getDatabase();if(!this.collection||!n)throw new Error(`Store ${this.name} is not provisioned`);if((await n.listCollections({name:e}).toArray()).length===0)throw new Error(`Collection ${e} not found`);if((await n.listCollections({name:this.name}).toArray()).length>0)throw new Error(`Collection ${this.name} already exists`);await n.collection(e).rename(this.name,o);}async vectorSearch({field:e,embedding:o,numCandidates:n,limit:r,projection:i,indexName:s}){return this.aggregate([{$vectorSearch:{index:s||e+"VectorSearch",path:e,queryVector:o,numCandidates:n||100,limit:r||10}},{$project:{_id:1,score:{$meta:"vectorSearchScore"},...i}}])}static vectorIndex({field:e,dimensions:o,similarity:n="cosine",indexName:r}){return {type:"vectorSearch",name:r||e+"VectorSearch",definition:{fields:[{type:"vector",path:e,numDimensions:o,similarity:n}]}}}};var Lt=z$1.string.bind(z$1),Ut=z$1.number.bind(z$1),jt=z$1.date.bind(z$1),$t=z$1.boolean.bind(z$1),Nt=z$1.array.bind(z$1),qt=z$1.object.bind(z$1),Bt=z$1.enum.bind(z$1),c={string:Lt,number:Ut,date:jt,boolean:$t,array:Nt,object:qt,enum:Bt,embedding(){return z$1.array(z$1.number())},objectId(){return z$1.instanceof(ObjectId)},userId(){return z$1.instanceof(ObjectId)},ref(t){return z$1.instanceof(ObjectId)},union:z$1.union.bind(z$1),infer(t){return {}}};var I=new y("_modelenceSessions",{schema:{authToken:c.string(),createdAt:c.date(),expiresAt:c.date(),userId:c.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function ke(t){let e=t?await I.findOne({authToken:t}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await L()}async function Ae(t,e){await I.updateOne({authToken:t},{$set:{userId:e}});}async function Pe(t){await I.updateOne({authToken:t},{$set:{userId:null}});}async function L(t=null){let e=randomBytes(32).toString("base64url"),o=Date.now(),n=new Date(o+a.days(7));return await I.insertOne({authToken:e,createdAt:new Date(o),expiresAt:n,userId:t}),{authToken:e,expiresAt:n,userId:t}}async function Wt(t){let e=Date.now(),o=new Date(e+a.days(7));await I.updateOne({authToken:t.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:o}});}var Le=new w("_system.session",{stores:[I],mutations:{init:async function(t,{session:e,user:o}){return {session:e,user:o,configs:b()}},heartbeat:async function(t,{session:e}){e&&await Wt(e);}}});var u=new y("_modelenceUsers",{schema:{handle:c.string(),emails:c.array(c.object({address:c.string(),verified:c.boolean()})).optional(),createdAt:c.date(),authMethods:c.object({password:c.object({hash:c.string()}).optional(),google:c.object({id:c.string()}).optional(),github:c.object({id:c.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}}]}),U=new y("_modelenceDisposableEmailDomains",{schema:{domain:c.string(),addedAt:c.date()},indexes:[{key:{domain:1},unique:true}]}),T=new y("_modelenceEmailVerificationTokens",{schema:{userId:c.objectId(),email:c.string().optional(),token:c.string(),createdAt:c.date(),expiresAt:c.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]}),v=new y("_modelenceResetPasswordTokens",{schema:{userId:c.objectId(),token:c.string(),createdAt:c.date(),expiresAt:c.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var Ue=new Map,M={authenticated:null,unauthenticated:null};function je(t,e){M.authenticated=e.authenticated,M.unauthenticated=e.unauthenticated;for(let[o,n]of Object.entries(t))Ue.set(o,n);}function V(){return M.unauthenticated?[M.unauthenticated]:[]}function $e(){return M.authenticated?[M.authenticated]:[]}function Ne(t,e){let o=e.find(n=>!Jt(t,n));if(o)throw new Error(`Access denied - missing permission: '${o}'`)}function Jt(t,e){for(let o of t){let n=Ue.get(o);if(n&&n.permissions.includes(e))return true}return false}async function j(t){let e=await ke(t),o=e.userId?await u.findOne({_id:new ObjectId(e.userId)}):null,n=o?{id:o._id.toString(),handle:o.handle}:null,r=n?$e():V();return {user:n,session:e,roles:r}}var S=null;async function qe(){if(S)return S;let t=$();if(!t)throw new Error("MongoDB URI is not set");S=new MongoClient(t,{maxPoolSize:20});try{return await S.connect(),await S.db("admin").command({ping:1}),console.log("Pinged your deployment. You successfully connected to MongoDB!"),S}catch(e){throw console.error(e),S=null,e}}function $(){let t=a$1("_system.mongodbUri");return t?String(t):void 0}function F(){return S}var N=null,Kt="_modelenceSocketio";async function Zt({httpServer:t,channels:e}){let o=F();if(!o)throw console.error("Socket.IO initialization failed: MongoDB client is not initialized"),new Error("Mongodb Client is not initialized");console.log("Initializing Socket.IO server...");let n=o.db().collection(Kt);try{await n.createIndex({createdAt:1},{expireAfterSeconds:3600,background:!0});}catch(r){console.error("Failed to create index on MongoDB collection for Socket.IO:",r);}N=new Server(t,{cors:{origin:"*",methods:["GET","POST"]},adapter:createAdapter(n),transports:["polling","websocket"],allowUpgrades:true,perMessageDeflate:false}),N.on("error",r=>{console.error("Socket.IO error:",r);}),N.use(async(r,i)=>{let s=r.handshake.auth.token;try{r.data=await j(s);}finally{i();}}),N.on("connection",r=>{console.log("Socket.IO client connected"),r.on("disconnect",()=>{console.log("Socket.IO client disconnected");}),r.on("joinChannel",async i=>{let[s]=i.split(":");for(let a of e)a.category===s&&(!a.canAccessChannel||await a.canAccessChannel(r.data))&&r.join(i);r.join(i),console.log(`User ${r.id} joined channel ${i}`),r.emit("joinedChannel",i);}),r.on("leaveChannel",i=>{r.leave(i),console.log(`User ${r.id} left channel ${i}`),r.emit("leftChannel",i);});}),console.log("Socket.IO server initialized");}function Qt({category:t,id:e,data:o}){N?.to(`${t}:${e}`).emit(t,o);}var Be={init:Zt,broadcast:Qt};async function ze(t){let e=t.toLowerCase().trim().split("@");if(e.length!==2)return false;let o=e[1];return !!await U.findOne({domain:o})}var We={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),n=new Date,r=500;for(let i=0;i<o.length;i+=r){let s=o.slice(i,i+r);try{await U.insertMany(s.map(a=>({domain:a,addedAt:n})));}catch(a){a.name==="MongoBulkWriteError"&&a.result?.nInserted;}}}};var ie=Object.freeze({});function Je(t){ie=Object.freeze(Object.assign({},ie,t));}function g(){return ie}function Yt(){return typeof window!="object"}function _(){if(!Yt())throw new Error("This function can only be called on the server")}function G(t){return t.replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim()}function He({name:t,email:e,verificationUrl:o}){return `
1
+ import {a as a$2}from'./chunk-3S2FFBNS.js';import {d,a as a$3}from'./chunk-C3UESBRX.js';import {a}from'./chunk-DO5TZLF5.js';import {b as b$1,e,d as d$1,c as c$1,f,g,i,a as a$1,h as h$1,j as j$1,k as k$1}from'./chunk-SOW7YLKS.js';export{a as getConfig}from'./chunk-SOW7YLKS.js';import At from'dotenv';import Jo from'fs/promises';import po from'os';import ge 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}from'crypto';import x,{z as z$1}from'zod';import oo from'bcrypt';import {createServer,defineConfig,loadConfigFromFile,mergeConfig}from'vite';import vo from'@vitejs/plugin-react';import Ro from'fs';import Ce,{Router}from'express';import zo from'cookie-parser';import Fo from'http';var b=class{constructor(e,{stores:o=[],queries:n={},mutations:r={},routes:i=[],cronJobs:s={},configSchema:a={},rateLimits:l=[],channels:p=[]}){this.name=e,this.stores=o,this.queries=n,this.mutations=r,this.routes=i,this.cronJobs=s,this.configSchema=a,this.rateLimits=l,this.channels=p;}};var y=class{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}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===68&&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 n=await this.requireCollection().findOne(e,o);return n?this.wrapDocument(n):null}async requireOne(e,o,n){let r=await this.findOne(e,o);if(!r)throw n?n():new Error(`Record not found in ${this.name}`);return r}find(e,o){let n=this.requireCollection().find(e);return o?.sort&&n.sort(o.sort),o?.limit&&n.limit(o.limit),o?.skip&&n.skip(o.skip),n}async findById(e){let o=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(o)}async requireById(e,o){let n=await this.findById(e);if(!n)throw o?o():new Error(`Record with id ${e} not found in ${this.name}`);return n}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,n){return await this.requireCollection().updateMany(e,o,n)}async upsertMany(e,o){return await this.requireCollection().updateMany(e,o,{upsert:true})}async deleteOne(e){return await this.requireCollection().deleteOne(e)}async deleteMany(e){return await this.requireCollection().deleteMany(e)}aggregate(e,o){return this.requireCollection().aggregate(e,o)}bulkWrite(e){return this.requireCollection().bulkWrite(e)}getDatabase(){return this.requireClient().db()}rawCollection(){return this.requireCollection()}async renameFrom(e,o){let n=this.getDatabase();if(!this.collection||!n)throw new Error(`Store ${this.name} is not provisioned`);if((await n.listCollections({name:e}).toArray()).length===0)throw new Error(`Collection ${e} not found`);if((await n.listCollections({name:this.name}).toArray()).length>0)throw new Error(`Collection ${this.name} already exists`);await n.collection(e).rename(this.name,o);}async vectorSearch({field:e,embedding:o,numCandidates:n,limit:r,projection:i,indexName:s}){return this.aggregate([{$vectorSearch:{index:s||e+"VectorSearch",path:e,queryVector:o,numCandidates:n||100,limit:r||10}},{$project:{_id:1,score:{$meta:"vectorSearchScore"},...i}}])}static vectorIndex({field:e,dimensions:o,similarity:n="cosine",indexName:r}){return {type:"vectorSearch",name:r||e+"VectorSearch",definition:{fields:[{type:"vector",path:e,numDimensions:o,similarity:n}]}}}};var Lt=z$1.string.bind(z$1),jt=z$1.number.bind(z$1),$t=z$1.date.bind(z$1),Nt=z$1.boolean.bind(z$1),qt=z$1.array.bind(z$1),zt=z$1.object.bind(z$1),Ft=z$1.enum.bind(z$1),c={string:Lt,number:jt,date:$t,boolean:Nt,array:qt,object:zt,enum:Ft,embedding(){return z$1.array(z$1.number())},objectId(){return z$1.instanceof(ObjectId)},userId(){return z$1.instanceof(ObjectId)},ref(t){return z$1.instanceof(ObjectId)},union:z$1.union.bind(z$1),infer(t){return {}}};var I=new y("_modelenceSessions",{schema:{authToken:c.string(),createdAt:c.date(),expiresAt:c.date(),userId:c.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function Me(t){let e=t?await I.findOne({authToken:t}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await se()}async function Pe(t,e){await I.updateOne({authToken:t},{$set:{userId:e}});}async function Ue(t){await I.updateOne({authToken:t},{$set:{userId:null}});}async function se(t=null){let e=randomBytes(32).toString("base64url"),o=Date.now(),n=new Date(o+a.days(7));return await I.insertOne({authToken:e,createdAt:new Date(o),expiresAt:n,userId:t}),{authToken:e,expiresAt:n,userId:t}}async function Wt(t){let e=Date.now(),o=new Date(e+a.days(7));await I.updateOne({authToken:t.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:o}});}var Le=new b("_system.session",{stores:[I],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 Wt(e);}}});var m=new y("_modelenceUsers",{schema:{handle:c.string(),emails:c.array(c.object({address:c.string(),verified:c.boolean()})).optional(),createdAt:c.date(),authMethods:c.object({password:c.object({hash:c.string()}).optional(),google:c.object({id:c.string()}).optional(),github:c.object({id:c.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}}]}),L=new y("_modelenceDisposableEmailDomains",{schema:{domain:c.string(),addedAt:c.date()},indexes:[{key:{domain:1},unique:true}]}),k=new y("_modelenceEmailVerificationTokens",{schema:{userId:c.objectId(),email:c.string().optional(),token:c.string(),createdAt:c.date(),expiresAt:c.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]}),_=new y("_modelenceResetPasswordTokens",{schema:{userId:c.objectId(),token:c.string(),createdAt:c.date(),expiresAt:c.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var je=new Map,D={authenticated:null,unauthenticated:null};function $e(t,e){D.authenticated=e.authenticated,D.unauthenticated=e.unauthenticated;for(let[o,n]of Object.entries(t))je.set(o,n);}function J(){return D.unauthenticated?[D.unauthenticated]:[]}function Ne(){return D.authenticated?[D.authenticated]:[]}function qe(t,e){let o=e.find(n=>!Jt(t,n));if(o)throw new Error(`Access denied - missing permission: '${o}'`)}function Jt(t,e){for(let o of t){let n=je.get(o);if(n&&n.permissions.includes(e))return true}return false}async function j(t){let e=await Me(t),o=e.userId?await m.findOne({_id:new ObjectId(e.userId)}):null,n=o?{id:o._id.toString(),handle:o.handle}:null,r=n?Ne():J();return {user:n,session:e,roles:r}}var S=null;async function ze(){if(S)return S;let t=$();if(!t)throw new Error("MongoDB URI is not set");S=new MongoClient(t,{maxPoolSize:20});try{return await S.connect(),await S.db("admin").command({ping:1}),console.log("Pinged your deployment. You successfully connected to MongoDB!"),S}catch(e){throw console.error(e),S=null,e}}function $(){let t=a$1("_system.mongodbUri");return t?String(t):void 0}function H(){return S}var N=null,Zt="_modelenceSocketio";async function Qt({httpServer:t,channels:e}){let o=H();if(!o)throw console.error("Socket.IO initialization failed: MongoDB client is not initialized"),new Error("Mongodb Client is not initialized");console.log("Initializing Socket.IO server...");let n=o.db().collection(Zt);try{await n.createIndex({createdAt:1},{expireAfterSeconds:3600,background:!0});}catch(r){console.error("Failed to create index on MongoDB collection for Socket.IO:",r);}N=new Server(t,{cors:{origin:"*",methods:["GET","POST"]},adapter:createAdapter(n),transports:["polling","websocket"],allowUpgrades:true,perMessageDeflate:false}),N.on("error",r=>{console.error("Socket.IO error:",r);}),N.use(async(r,i)=>{let s=r.handshake.auth.token;try{r.data=await j(s);}finally{i();}}),N.on("connection",r=>{console.log("Socket.IO client connected"),r.on("disconnect",()=>{console.log("Socket.IO client disconnected");}),r.on("joinChannel",async i=>{let[s]=i.split(":");for(let a of e)a.category===s&&(!a.canAccessChannel||await a.canAccessChannel(r.data))&&r.join(i);r.join(i),console.log(`User ${r.id} joined channel ${i}`),r.emit("joinedChannel",i);}),r.on("leaveChannel",i=>{r.leave(i),console.log(`User ${r.id} left channel ${i}`),r.emit("leftChannel",i);});}),console.log("Socket.IO server initialized");}function Yt({category:t,id:e,data:o}){N?.to(`${t}:${e}`).emit(t,o);}var Fe={init:Qt,broadcast:Yt};async function Be(t){let e=t.toLowerCase().trim().split("@");if(e.length!==2)return false;let o=e[1];return !!await L.findOne({domain:o})}var We={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),n=new Date,r=500;for(let i=0;i<o.length;i+=r){let s=o.slice(i,i+r);try{await L.insertMany(s.map(a=>({domain:a,addedAt:n})));}catch(a){a&&typeof a=="object"&&"name"in a&&a.name;}}}};var ae=Object.freeze({});function Je(t){ae=Object.freeze(Object.assign({},ae,t));}function w(){return ae}function Xt(){return typeof window!="object"}function v(){if(!Xt())throw new Error("This function can only be called on the server")}function V(t){return t.replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim()}function He({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
- `}async function Ve(t){let e=process.env.MODELENCE_SITE_URL,o=g().emailVerifiedRedirectUrl||e||"/";try{let n=z$1.string().parse(t.query.token),r=await T.findOne({token:n,expiresAt:{$gt:new Date}});if(!r)throw new Error("Invalid or expired verification token");if(!await u.findOne({_id:r.userId}))throw new Error("User not found");let s=r.email;if(!s)throw new Error("Email not found in token");if((await u.updateOne({_id:r.userId,"emails.address":s,"emails.verified":{$ne:!0}},{$set:{"emails.$.verified":!0}})).matchedCount===0)throw await u.findOne({_id:r.userId,"emails.address":s})?new Error("Email is already verified"):new Error("Email address not found for this user");await T.deleteOne({_id:r._id});}catch(n){if(n instanceof Error)return console.error("Error verifying email:",n),{status:301,redirect:`${o}?status=error&message=${encodeURIComponent(n.message)}`}}return {status:301,redirect:`${o}?status=verified`}}async function K({userId:t,email:e,baseUrl:o=process.env.MODELENCE_SITE_URL}){if(g().provider){let n=g().provider,r=randomBytes(32).toString("hex"),i=new Date(Date.now()+a.hours(24));await T.insertOne({userId:t,email:e,token:r,createdAt:new Date,expiresAt:i});let s=`${o}/api/_internal/auth/verify-email?token=${r}`,l=(g()?.verification?.template||He)({name:"",email:e,verificationUrl:s}),d=G(l);await n?.sendEmail({to:e,from:g()?.from||"noreply@modelence.com",subject:g()?.verification?.subject||"Verify your email address",text:d,html:l});}}function Z(t){return z$1.string().min(8,{message:"Password must contain at least 8 characters"}).parse(t)}function k(t){return z$1.string().email({message:"Invalid email address"}).parse(t)}var se=Object.freeze({});function Ge(t){se=Object.freeze(Object.assign({},se,t));}function p(){return se}async function Ze(t,{user:e,session:o,connectionInfo:n}){try{if(!o)throw new Error("Session is not initialized");let r=n?.ip;r&&await R({bucket:"signin",type:"ip",value:r});let i=k(t.email),s=z$1.string().parse(t.password),a=await u.findOne({"emails.address":i},{collation:{locale:"en",strength:2}}),l=a?.authMethods?.password?.hash;if(!l)throw Ke();if(!a.emails?.find(m=>m.address===i)?.verified&&g()?.provider){if(r)try{await R({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 K({userId:a?._id,email:i,baseUrl:n?.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,l))throw Ke();return await Ae(o.authToken,a._id),p().onAfterLogin?.({user:a,session:o,connectionInfo:n}),p().login?.onSuccess?.(a),{user:{id:a._id,handle:a.handle}}}catch(r){throw r instanceof Error&&(p().onLoginError?.({error:r,session:o,connectionInfo:n}),p().login?.onError?.(r)),r}}async function Qe(t,{user:e,session:o}){if(!o)throw new Error("Session is not initialized");await Pe(o.authToken);}function Ke(){return new Error("Incorrect email/password combination")}async function Ye(t,{user:e}){if(!e)throw new Error("Not authenticated");let o=await u.requireById(e.id);return {handle:o.handle,emails:o.emails,authMethods:Object.keys(o.authMethods||{})}}var q=new y("_modelenceRateLimits",{schema:{bucket:c.string(),type:c.enum(["ip","user"]),value:c.string(),windowMs:c.number(),windowStart:c.date(),windowCount:c.number(),prevWindowCount:c.number(),expiresAt:c.date()},indexes:[{key:{bucket:1,type:1,value:1,windowMs:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var ae=[];function Xe(t){if(ae.length>0)throw new Error("Duplicate call to initRateLimits - already initialized");ae=t;}async function R(t){let{bucket:e,type:o,value:n}=t,r=ae.filter(i=>i.bucket===e&&i.type===o);for(let i of r)await no(i,n);}async function no(t,e,o){let n=()=>new d(`Rate limit exceeded for ${t.bucket}`),r=await q.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:l}=r?ro(r,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 n();await q.upsertOne({bucket:t.bucket,type:t.type,value:e,windowMs:t.window},l);}function ro(t,e,o){let n=e-t.windowMs;if(t.windowStart.getTime()===e){let r=t.windowCount,i=t.prevWindowCount,s=1-(o-e)/t.windowMs;return {count:Math.round(r+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()===n){let r=1-(o-e)/t.windowMs;return {count:Math.round(t.windowCount*r),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 et(t,{user:e,session:o,connectionInfo:n}){try{let r=k(t.email),i=Z(t.password),s=n?.ip;if(s&&await R({bucket:"signupAttempt",type:"ip",value:s}),await ze(r))throw new Error("Please use a permanent email address");let a=await u.findOne({"emails.address":r},{collation:{locale:"en",strength:2}});if(a){let m=a.emails?.find(C=>C.address===r);throw new Error(`User with email already exists: ${m?.address}`)}s&&await R({bucket:"signup",type:"ip",value:s});let l=await to.hash(i,10),d=await u.insertOne({handle:r,emails:[{address:r,verified:!1}],createdAt:new Date,authMethods:{password:{hash:l}}}),E=await u.findOne({_id:d.insertedId},{readPreference:"primary"});if(!E)throw new Error("User not found");return await K({userId:d?.insertedId,email:r,baseUrl:n?.baseUrl}),p().onAfterSignup?.({user:E,session:o,connectionInfo:n}),p().signup?.onSuccess?.(E),d.insertedId}catch(r){throw r instanceof Error&&(p().onSignupError?.({error:r,session:o,connectionInfo:n}),p().signup?.onError?.(r)),r}}function lo(t,e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${t}${e.startsWith("/")?"":"/"}${e}`:t}function uo({email:t,resetUrl:e}){return `
7
+ `}async function Ve(t){let e=process.env.MODELENCE_SITE_URL,o=w().emailVerifiedRedirectUrl||e||"/";try{let n=z$1.string().parse(t.query.token),r=await k.findOne({token:n,expiresAt:{$gt:new Date}});if(!r)throw new Error("Invalid or expired verification token");if(!await m.findOne({_id:r.userId}))throw new Error("User not found");let s=r.email;if(!s)throw new Error("Email not found in token");if((await m.updateOne({_id:r.userId,"emails.address":s,"emails.verified":{$ne:!0}},{$set:{"emails.$.verified":!0}})).matchedCount===0)throw await m.findOne({_id:r.userId,"emails.address":s})?new Error("Email is already verified"):new Error("Email address not found for this user");await k.deleteOne({_id:r._id});}catch(n){if(n instanceof Error)return console.error("Error verifying email:",n),{status:301,redirect:`${o}?status=error&message=${encodeURIComponent(n.message)}`}}return {status:301,redirect:`${o}?status=verified`}}async function G({userId:t,email:e,baseUrl:o=process.env.MODELENCE_SITE_URL}){if(w().provider){let n=w().provider,r=randomBytes(32).toString("hex"),i=new Date(Date.now()+a.hours(24));await k.insertOne({userId:t,email:e,token:r,createdAt:new Date,expiresAt:i});let s=`${o}/api/_internal/auth/verify-email?token=${r}`,l=(w()?.verification?.template||He)({name:"",email:e,verificationUrl:s}),p=V(l);await n?.sendEmail({to:e,from:w()?.from||"noreply@modelence.com",subject:w()?.verification?.subject||"Verify your email address",text:p,html:l});}}function K(t){return z$1.string().min(8,{message:"Password must contain at least 8 characters"}).parse(t)}function A(t){return z$1.string().email({message:"Invalid email address"}).parse(t)}var ce=Object.freeze({});function Ke(t){ce=Object.freeze(Object.assign({},ce,t));}function h(){return ce}async function Qe(t,{user:e,session:o,connectionInfo:n}){try{if(!o)throw new Error("Session is not initialized");let r=n?.ip;r&&await R({bucket:"signin",type:"ip",value:r});let i=A(t.email),s=z$1.string().parse(t.password),a=await m.findOne({"emails.address":i},{collation:{locale:"en",strength:2}}),l=a?.authMethods?.password?.hash;if(!l)throw Ze();if(!a.emails?.find(u=>u.address===i)?.verified&&w()?.provider){if(r)try{await R({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 G({userId:a?._id,email:i,baseUrl:n?.baseUrl}),new Error("Your email address hasn't been verified yet. We've sent a new verification email to your inbox.")}if(!await oo.compare(s,l))throw Ze();return await Pe(o.authToken,a._id),h().onAfterLogin?.({user:a,session:o,connectionInfo:n}),h().login?.onSuccess?.(a),{user:{id:a._id,handle:a.handle}}}catch(r){throw r instanceof Error&&(h().onLoginError?.({error:r,session:o,connectionInfo:n}),h().login?.onError?.(r)),r}}async function Ye(t,{session:e}){if(!e)throw new Error("Session is not initialized");await Ue(e.authToken);}function Ze(){return new Error("Incorrect email/password combination")}async function Xe(t,{user:e}){if(!e)throw new Error("Not authenticated");let o=await m.requireById(e.id);return {handle:o.handle,emails:o.emails,authMethods:Object.keys(o.authMethods||{})}}var q=new y("_modelenceRateLimits",{schema:{bucket:c.string(),type:c.enum(["ip","user"]),value:c.string(),windowMs:c.number(),windowStart:c.date(),windowCount:c.number(),prevWindowCount:c.number(),expiresAt:c.date()},indexes:[{key:{bucket:1,type:1,value:1,windowMs:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var le=[];function et(t){if(le.length>0)throw new Error("Duplicate call to initRateLimits - already initialized");le=t;}async function R(t){let{bucket:e,type:o,value:n}=t,r=le.filter(i=>i.bucket===e&&i.type===o);for(let i of r)await ro(i,n);}async function ro(t,e,o){let n=()=>new d(`Rate limit exceeded for ${t.bucket}`),r=await q.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:l}=r?io(r,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 n();await q.upsertOne({bucket:t.bucket,type:t.type,value:e,windowMs:t.window},l);}function io(t,e,o){let n=e-t.windowMs;if(t.windowStart.getTime()===e){let r=t.windowCount,i=t.prevWindowCount,s=1-(o-e)/t.windowMs;return {count:Math.round(r+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()===n){let r=1-(o-e)/t.windowMs;return {count:Math.round(t.windowCount*r),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 tt(t,{user:e,session:o,connectionInfo:n}){try{let r=A(t.email),i=K(t.password),s=n?.ip;if(s&&await R({bucket:"signupAttempt",type:"ip",value:s}),await Be(r))throw new Error("Please use a permanent email address");let a=await m.findOne({"emails.address":r},{collation:{locale:"en",strength:2}});if(a){let u=a.emails?.find(E=>E.address===r);throw new Error(`User with email already exists: ${u?.address}`)}s&&await R({bucket:"signup",type:"ip",value:s});let l=await oo.hash(i,10),p=await m.insertOne({handle:r,emails:[{address:r,verified:!1}],createdAt:new Date,authMethods:{password:{hash:l}}}),C=await m.findOne({_id:p.insertedId},{readPreference:"primary"});if(!C)throw new Error("User not found");return await G({userId:p?.insertedId,email:r,baseUrl:n?.baseUrl}),h().onAfterSignup?.({user:C,session:o,connectionInfo:n}),h().signup?.onSuccess?.(C),p.insertedId}catch(r){throw r instanceof Error&&(h().onSignupError?.({error:r,session:o,connectionInfo:n}),h().signup?.onError?.(r)),r}}function uo(t,e){return e?e.startsWith("http://")||e.startsWith("https://")?e:`${t}${e.startsWith("/")?"":"/"}${e}`:t}function mo({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 ce={success:true,message:"If an account with that email exists, a password reset link has been sent"};async function tt(t,{connectionInfo:e}){let o=k(t.email),n=await u.findOne({"emails.address":o},{collation:{locale:"en",strength:2}});if(!n||!n.authMethods?.password)return ce;let r=g().provider;if(!r)throw new Error("Email provider is not configured");let i=randomBytes(32).toString("hex"),s=new Date(Date.now()+a.hours(1));await v.insertOne({userId:n._id,token:i,createdAt:new Date,expiresAt:s});let a$1=process.env.MODELENCE_SITE_URL||e?.baseUrl,d=`${lo(a$1,g().passwordReset?.redirectUrl)}?token=${i}`,m=(g()?.passwordReset?.template||uo)({email:o,resetUrl:d,name:""}),C=G(m);return await r.sendEmail({to:o,from:g()?.from||"noreply@modelence.com",subject:g()?.passwordReset?.subject||"Reset your password",text:C,html:m}),ce}async function ot(t,{}){let e=z$1.string().parse(t.token),o=Z(t.password),n=await v.findOne({token:e});if(!n)throw new Error("Invalid or expired reset token");if(n.expiresAt<new Date)throw await v.deleteOne({token:e}),new Error("Reset token has expired");let r=await u.findOne({_id:n.userId});if(!r)throw new Error("User not found");let i=await to.hash(o,10);return await u.updateOne({_id:r._id},{$set:{"authMethods.password.hash":i}}),await v.deleteOne({token:e}),{success:true,message:"Password has been reset successfully"}}var nt=new w("_system.user",{stores:[u,U,T,v],queries:{getOwnProfile:Ye},mutations:{signupWithPassword:et,loginWithPassword:Ze,logout:Qe,sendResetPasswordToken:tt,resetPassword:ot},cronJobs:{updateDisposableEmailList:We},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:Ve}}]});async function rt({configSchema:t,cronJobsMetadata:e,stores:o}){let n=process.env.MODELENCE_CONTAINER_ID;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set");try{let r=Object.values(o).map(s=>({name:s.getName(),schema:s.getSchema(),collections:[s.getName()]})),i=await le("/api/connect","POST",{hostname:mo.hostname(),containerId:n,dataModels:r,configSchema:t,cronJobsMetadata:e});if(i.status==="error")throw new Error(i.error);return console.log("Successfully connected to Modelence Cloud"),i}catch(r){throw console.error("Unable to connect to Modelence Cloud:",r),r}}async function it(){return await le("/api/configs","GET")}async function st(){return await le("/api/sync","POST",{containerId:process.env.MODELENCE_CONTAINER_ID})}async function le(t,e,o){let{MODELENCE_SERVICE_ENDPOINT:n,MODELENCE_SERVICE_TOKEN:r}=process.env;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set");let i=await fetch(`${n}${t}`,{method:e,headers:{Authorization:`Bearer ${r}`,...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 ue=false,po=a.seconds(10);function at(){setInterval(async()=>{if(!ue){ue=true;try{await st();}catch(t){console.error("Error syncing status",t);}try{await fo();}catch(t){console.error("Error syncing config",t);}ue=false;}},po);}async function fo(){let{configs:t}=await it();c$1(t);}var ho=a.minutes(1),go=a.seconds(10),D={},de,B=new y("_modelenceCronJobs",{schema:{alias:c.string(),lastStartDate:c.date().optional(),lock:c.object({containerId:c.string(),acquireDate:c.date()}).optional()},indexes:[{key:{alias:1},unique:true,background:true}]});function lt(t,{description:e="",interval:o,timeout:n=ho,handler:r}){if(D[t])throw new Error(`Duplicate cron job declaration: '${t}' already exists`);if(de)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(n>a.days(1))throw new Error(`Cron job timeout should not be longer than 1 day [${t}]`);D[t]={alias:t,params:{description:e,interval:o,timeout:n},handler:r,state:{isRunning:false}};}async function ut(){if(de)throw new Error("Cron jobs already started");let t=Object.keys(D);if(t.length>0){let e={alias:{$in:t}},o=await B.findOne({...e,"lock.containerId":{$exists:true}});await Promise.all(t.map(i=>B.upsertOne({alias:i},{$set:{lock:{containerId:process.env.MODELENCE_CONTAINER_ID||"unknown",acquireDate:new Date}}}))),o&&await yo(go);let n=await B.fetch(e),r=Date.now();n.forEach(i=>{let s=D[i.alias];s&&(s.state.scheduledRunTs=i.lastStartDate?i.lastStartDate.getTime()+s.params.interval:r);}),Object.values(D).forEach(i=>{i.state.scheduledRunTs||(i.state.scheduledRunTs=r);}),de=setInterval(wo,a.seconds(1));}}function yo(t){return new Promise(e=>setTimeout(e,t))}async function wo(){let t=Date.now();Object.values(D).forEach(async e=>{let{params:o,state:n}=e;if(n.isRunning){n.startTs&&n.startTs+o.timeout<t&&(n.isRunning=false);return}n.scheduledRunTs&&n.scheduledRunTs<=t&&await bo(e);});}async function bo(t){let{alias:e,params:o,handler:n,state:r}=t;r.isRunning=true,r.startTs=Date.now();let i=j$1("cron",`cron:${e}`);n().then(()=>{ct(r,o),i.end("success");}).catch(s=>{ct(r,o),k$1(s),i.end("error"),console.error(`Error in cron job '${e}':`,s);}),await B.updateOne({alias:e},{$set:{lastStartDate:new Date(r.startTs)}});}function ct(t,e){t.scheduledRunTs=t.startTs?t.startTs+e.interval:Date.now(),t.startTs=void 0,t.isRunning=false;}function dt(){return Object.values(D).map(({alias:t,params:e})=>({alias:t,description:e.description,interval:e.interval,timeout:e.timeout}))}var mt=new w("_system.cron",{stores:[B]});var me={};function pe(t,e){return _(),gt(t),Q("query",t,e)}function pt(t,e){return _(),gt(t),Q("mutation",t,e)}function ft(t,e){return _(),yt(t),Q("query",t,e)}function ht(t,e){return _(),yt(t),Q("mutation",t,e)}function gt(t){if(t.toLowerCase().startsWith("_system."))throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${t})`)}function yt(t){if(!t.toLowerCase().startsWith("_system."))throw new Error(`System method name must start with a prefix: '_system.' (${t})`)}function Q(t,e,o){if(_(),me[e])throw new Error(`Method with name '${e}' is already defined.`);let n=typeof o=="function"?o:o.handler,r=typeof o=="function"?[]:o.permissions??[];me[e]={type:t,name:e,handler:n,permissions:r};}async function wt(t,e,o){_();let n=me[t];if(!n)throw new Error(`Method with name '${t}' is not defined.`);let{type:r,handler:i}=n,s=j$1("method",`method:${t}`,{type:r,args:e}),a;try{Ne(o.roles,n.permissions),a=await i(e,o);}catch(l){throw s.end("error"),l}return s.end(),a}var Y=new y("_modelenceMigrations",{schema:{version:c.number(),appliedAt:c.date()},indexes:[{key:{version:1},unique:true}]});async function bt(t){if(t.length===0)return;let e=t.map(({version:i})=>i),o=await Y.fetch({version:{$in:e}}),n=new Set(o.map(({version:i})=>i)),r=t.filter(({version:i})=>!n.has(i));if(r.length!==0){console.log(`Running migrations (${r.length})...`);for(let{version:i,description:s,handler:a}of r)console.log(`Running migration v${i}: ${s}`),await Y.insertOne({version:i,appliedAt:new Date}),await a(),console.log(`Migration v${i} complete`);}}var Et=new w("_system.migration",{stores:[Y]});var Ct=new w("_system.rateLimit",{stores:[q]});var he=class{async init(){this.config=await Oo(),this.isDev()&&(console.log("Starting Vite dev server..."),this.viteServer=await createServer(this.config));}middlewares(){if(this.isDev())return this.viteServer?.middlewares??[];let e=[be.static("./.modelence/build/client".replace(/\\/g,"/"))];return this.config?.publicDir&&e.push(be.static(this.config.publicDir)),e}handler(e,o){if(this.isDev())try{o.sendFile("index.html",{root:"./src/client"});}catch(n){console.error("Error serving index.html:",n),o.status(500).send("Internal Server Error");}else o.sendFile("index.html",{root:"./.modelence/build/client".replace(/\\/g,"/")});}isDev(){return process.env.NODE_ENV!=="production"}};async function Ro(){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 Do(t,e){let o=mergeConfig(t,e);if(o.plugins&&Array.isArray(o.plugins)){let n=new Set;o.plugins=o.plugins.flat().filter(r=>{if(!r||typeof r!="object")return true;let i=r.name;return !i||n.has(i)?false:(n.add(i),true)}).reverse(),o.plugins.reverse();}return o}async function Oo(){let t=process.cwd(),e=await Ro(),o=[".eslintrc.js",".eslintrc.json",".eslintrc","eslint.config.js",".eslintrc.yml",".eslintrc.yaml"].find(i=>_o.existsSync(fe.join(t,i))),n=[vo(),Io()];if(o){let i=(await import('vite-plugin-eslint')).default;n.push(i({failOnError:false,include:["src/**/*.js","src/**/*.jsx","src/**/*.ts","src/**/*.tsx"],cwd:t,overrideConfigFile:fe.resolve(t,o)}));}let r=defineConfig({plugins:n,build:{outDir:".modelence/build/client".replace(/\\/g,"/"),emptyOutDir:true},server:{middlewareMode:true},root:"./src/client",resolve:{alias:{"@":fe.resolve(t,"src").replace(/\\/g,"/")}}});return Do(r,e)}function Io(){return {name:"modelence-asset-handler",async transform(t,e){if(/\.(png|jpe?g|gif|svg|mpwebm|ogg|mp3|wav|flac|aac)$/.test(e))return process.env.NODE_ENV==="development",t},async generateBundle(t,e){}}}var xt=new he;async function vt(t,e){let{authToken:o}=await L(e);t.cookie("authToken",o,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"strict"}),t.status(301),t.redirect("/");}async function ko(t,e){let o=t.user,n=await u.findOne({"authMethods.google.id":o.id}),{session:r,connectionInfo:i}=await z(t);try{if(n){await vt(e,n._id),p().onAfterLogin?.({user:n,session:r,connectionInfo:i}),p().login?.onSuccess?.(n);return}}catch(s){throw s instanceof Error&&(p().login?.onError?.(s),p().onLoginError?.({error:s,session:r,connectionInfo:i})),s}try{let s=o.emails[0]&&o.emails[0]?.value;if(s||e.status(400).json({error:"Email address is required for Google authentication."}),await u.findOne({"emails.address":s},{collation:{locale:"en",strength:2}})){e.status(400).json({error:"User with this email already exists. Please log in instead."});return}let l=await u.insertOne({handle:s,emails:[{address:s,verified:!0}],createdAt:new Date,authMethods:{google:{id:o.id}}});await vt(e,l.insertedId);let d=await u.findOne({_id:l.insertedId},{readPreference:"primary"});d&&(p().onAfterSignup?.({user:d,session:r,connectionInfo:i}),p().signup?.onSuccess?.(d));}catch(s){throw s instanceof Error&&(p().onSignupError?.({error:s,session:r,connectionInfo:i}),p().signup?.onError?.(s)),s}}function Ao(){let t=Router(),e=!!a$1("_system.user.auth.google.enabled"),o=String(a$1("_system.user.auth.google.clientId")),n=String(a$1("_system.user.auth.google.clientSecret"));return !e||!o||!n||(ge.use(new Strategy({clientID:o,clientSecret:n,callbackURL:"/api/_internal/auth/google/callback",proxy:true},(r,i,s,a)=>a(null,s))),t.get("/api/_internal/auth/google",ge.authenticate("google",{scope:["profile","email"],session:false})),t.get("/api/_internal/auth/google/callback",ge.authenticate("google",{session:false}),ko)),t}var _t=Ao;async function Rt(t,e){let{authToken:o}=await L(e);t.cookie("authToken",o,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"strict"}),t.status(301),t.redirect("/");}async function Uo(t,e){let o=t.user,n=await u.findOne({"authMethods.github.id":o.id}),{session:r,connectionInfo:i}=await z(t);try{if(n){await Rt(e,n._id),p().onAfterLogin?.({user:n,session:r,connectionInfo:i}),p().login?.onSuccess?.(n);return}}catch(s){throw s instanceof Error&&(p().login?.onError?.(s),p().onLoginError?.({error:s,session:r,connectionInfo:i})),s}try{let s=o.emails[0]&&o.emails[0]?.value;if(s||e.status(400).json({error:"Email address is required for GitHub authentication."}),await u.findOne({"emails.address":s},{collation:{locale:"en",strength:2}})){e.status(400).json({error:"User with this email already exists. Please log in instead."});return}let l=await u.insertOne({handle:s,emails:[{address:s,verified:!0}],createdAt:new Date,authMethods:{github:{id:o.id}}});await Rt(e,l.insertedId);let d=await u.findOne({_id:l.insertedId},{readPreference:"primary"});d&&(p().onAfterSignup?.({user:d,session:r,connectionInfo:i}),p().signup?.onSuccess?.(d));}catch(s){throw s instanceof Error&&(p().onSignupError?.({error:s,session:r,connectionInfo:i}),p().signup?.onError?.(s)),s}}function jo(){let t=Router(),e=!!a$1("_system.user.auth.github.enabled");console.log(e);let o=String(a$1("_system.user.auth.github.clientId")),n=String(a$1("_system.user.auth.github.clientSecret")),r=a$1("_system.user.auth.github.scopes");if(!e||!o||!n)return t;let i=r?String(r).split(",").map(s=>s.trim()):["user:email"];return ge.use(new Strategy$1({clientID:o,clientSecret:n,callbackURL:"/api/_internal/auth/github/callback",scope:i},(s,a,l,d)=>d(null,l))),t.get("/api/_internal/auth/github",ge.authenticate("github",{session:false})),t.get("/api/_internal/auth/github/callback",ge.authenticate("github",{session:false}),Uo),t}var Dt=jo;function Ot(t){return async(e,o)=>{try{let n=await t({query:e.query,body:e.body,params:e.params,headers:e.headers,cookies:e.cookies,req:e});o.status(n.status||200),n.redirect&&o.redirect(n.redirect),n.headers&&Object.entries(n.headers).forEach(([r,i])=>{o.setHeader(r,i);}),o.send(n.data);}catch(n){n instanceof a$3?o.status(n.status).send(n.message):(console.error(`Error in route handler: ${e.path}`),console.error(n),o.status(500).send(String(n)));}}}var we=Object.freeze({});function It(t){we=Object.freeze(Object.assign({},we,t));}function X(){return we}function Bo(t,e){for(let o of e)for(let n of o.routes){let{path:r,handlers:i}=n;Object.entries(i).forEach(([s,a])=>{t[s](r,Ot(a));});}}async function Tt(t,{combinedModules:e,channels:o}){let n=be();n.use(be.json()),n.use(be.urlencoded({extended:true})),n.use($o()),n.use(ge.initialize()),n.use(_t()),n.use(Dt()),n.post("/api/_internal/method/:methodName(*)",async(a,l)=>{let{methodName:d}=a.params,E=await z(a);try{let m=await wt(d,a.body.args,E);l.json({data:m,typeMap:a$2(m)});}catch(m){if(console.error(`Error in method ${d}:`,m),m instanceof a$3)l.status(m.status).send(m.message);else if(m instanceof Error&&m?.constructor?.name==="ZodError"&&"errors"in m){let O=m.flatten(),ee=Object.entries(O.fieldErrors).map(([A,oe])=>`${A}: ${(oe??[]).join(", ")}`).join("; "),te=O.formErrors.join("; "),W=[ee,te].filter(Boolean).join("; ");l.status(400).send(W);}else l.status(500).send(m instanceof Error?m.message:String(m));}}),Bo(n,e),await t.init(),t.middlewares&&n.use(t.middlewares()),n.all("*",(a,l)=>t.handler(a,l)),process.on("unhandledRejection",(a,l)=>{console.error("Unhandled Promise Rejection:"),console.error(a instanceof Error?a.stack:a),console.error("Promise:",l);}),process.on("uncaughtException",a=>{console.error("Uncaught Exception:"),console.error(a.stack),console.trace("Full application stack:");});let r=No.createServer(n),i=X()?.provider;i&&i.init({httpServer:r,channels:o});let s=process.env.MODELENCE_PORT||process.env.PORT||3e3;r.listen(s,()=>{h("Application started",{source:"app"}),console.log(`
14
+ `}var ue={success:true,message:"If an account with that email exists, a password reset link has been sent"};async function ot(t,{connectionInfo:e}){let o=A(t.email),n=await m.findOne({"emails.address":o},{collation:{locale:"en",strength:2}});if(!n||!n.authMethods?.password)return ue;let r=w().provider;if(!r)throw new Error("Email provider is not configured");let i=randomBytes(32).toString("hex"),s=new Date(Date.now()+a.hours(1));await _.insertOne({userId:n._id,token:i,createdAt:new Date,expiresAt:s});let a$1=process.env.MODELENCE_SITE_URL||e?.baseUrl,p=`${uo(a$1,w().passwordReset?.redirectUrl)}?token=${i}`,u=(w()?.passwordReset?.template||mo)({email:o,resetUrl:p,name:""}),E=V(u);return await r.sendEmail({to:o,from:w()?.from||"noreply@modelence.com",subject:w()?.passwordReset?.subject||"Reset your password",text:E,html:u}),ue}async function nt(t,{}){let e=z$1.string().parse(t.token),o=K(t.password),n=await _.findOne({token:e});if(!n)throw new Error("Invalid or expired reset token");if(n.expiresAt<new Date)throw await _.deleteOne({token:e}),new Error("Reset token has expired");let r=await m.findOne({_id:n.userId});if(!r)throw new Error("User not found");let i=await oo.hash(o,10);return await m.updateOne({_id:r._id},{$set:{"authMethods.password.hash":i}}),await _.deleteOne({token:e}),{success:true,message:"Password has been reset successfully"}}var rt=new b("_system.user",{stores:[m,L,k,_],queries:{getOwnProfile:Xe},mutations:{signupWithPassword:tt,loginWithPassword:Qe,logout:Ye,sendResetPasswordToken:ot,resetPassword:nt},cronJobs:{updateDisposableEmailList:We},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:Ve}}]});async function it({configSchema:t,cronJobsMetadata:e,stores:o}){let n=process.env.MODELENCE_CONTAINER_ID;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_CONTAINER_ID is not set");try{let r=Object.values(o).map(s=>({name:s.getName(),schema:s.getSchema(),collections:[s.getName()]})),i=await de("/api/connect","POST",{hostname:po.hostname(),containerId:n,dataModels:r,configSchema:t,cronJobsMetadata:e});if(i.status==="error")throw new Error(i.error);return console.log("Successfully connected to Modelence Cloud"),i}catch(r){throw console.error("Unable to connect to Modelence Cloud:",r),r}}async function st(){return await de("/api/configs","GET")}async function at(){return await de("/api/sync","POST",{containerId:process.env.MODELENCE_CONTAINER_ID})}async function de(t,e,o){let{MODELENCE_SERVICE_ENDPOINT:n,MODELENCE_SERVICE_TOKEN:r}=process.env;if(!n)throw new Error("Unable to connect to Modelence Cloud: MODELENCE_SERVICE_ENDPOINT is not set");let i=await fetch(`${n}${t}`,{method:e,headers:{Authorization:`Bearer ${r}`,...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 me=false,fo=a.seconds(10);function ct(){setInterval(async()=>{if(!me){me=true;try{await at();}catch(t){console.error("Error syncing status",t);}try{await ho();}catch(t){console.error("Error syncing config",t);}me=false;}},fo);}async function ho(){let{configs:t}=await st();c$1(t);}var go=a.minutes(1),wo=a.seconds(10),O={},pe,z=new y("_modelenceCronJobs",{schema:{alias:c.string(),lastStartDate:c.date().optional(),lock:c.object({containerId:c.string(),acquireDate:c.date()}).optional()},indexes:[{key:{alias:1},unique:true,background:true}]});function ut(t,{description:e="",interval:o,timeout:n=go,handler:r}){if(O[t])throw new Error(`Duplicate cron job declaration: '${t}' already exists`);if(pe)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(n>a.days(1))throw new Error(`Cron job timeout should not be longer than 1 day [${t}]`);O[t]={alias:t,params:{description:e,interval:o,timeout:n},handler:r,state:{isRunning:false}};}async function dt(){if(pe)throw new Error("Cron jobs already started");let t=Object.keys(O);if(t.length>0){let e={alias:{$in:t}},o=await z.findOne({...e,"lock.containerId":{$exists:true}});await Promise.all(t.map(i=>z.upsertOne({alias:i},{$set:{lock:{containerId:process.env.MODELENCE_CONTAINER_ID||"unknown",acquireDate:new Date}}}))),o&&await yo(wo);let n=await z.fetch(e),r=Date.now();n.forEach(i=>{let s=O[i.alias];s&&(s.state.scheduledRunTs=i.lastStartDate?i.lastStartDate.getTime()+s.params.interval:r);}),Object.values(O).forEach(i=>{i.state.scheduledRunTs||(i.state.scheduledRunTs=r);}),pe=setInterval(bo,a.seconds(1));}}function yo(t){return new Promise(e=>setTimeout(e,t))}async function bo(){let t=Date.now();Object.values(O).forEach(async e=>{let{params:o,state:n}=e;if(n.isRunning){n.startTs&&n.startTs+o.timeout<t&&(n.isRunning=false);return}n.scheduledRunTs&&n.scheduledRunTs<=t&&await Co(e);});}async function Co(t){let{alias:e,params:o,handler:n,state:r}=t;r.isRunning=true,r.startTs=Date.now();let i=j$1("cron",`cron:${e}`);n().then(()=>{lt(r,o),i.end("success");}).catch(s=>{lt(r,o),k$1(s),i.end("error"),console.error(`Error in cron job '${e}':`,s);}),await z.updateOne({alias:e},{$set:{lastStartDate:new Date(r.startTs)}});}function lt(t,e){t.scheduledRunTs=t.startTs?t.startTs+e.interval:Date.now(),t.startTs=void 0,t.isRunning=false;}function mt(){return Object.values(O).map(({alias:t,params:e})=>({alias:t,description:e.description,interval:e.interval,timeout:e.timeout}))}var pt=new b("_system.cron",{stores:[z]});var fe={};function he(t,e){return v(),wt(t),Z("query",t,e)}function ft(t,e){return v(),wt(t),Z("mutation",t,e)}function ht(t,e){return v(),yt(t),Z("query",t,e)}function gt(t,e){return v(),yt(t),Z("mutation",t,e)}function wt(t){if(t.toLowerCase().startsWith("_system."))throw new Error(`Method name cannot start with a reserved prefix: '_system.' (${t})`)}function yt(t){if(!t.toLowerCase().startsWith("_system."))throw new Error(`System method name must start with a prefix: '_system.' (${t})`)}function Z(t,e,o){if(v(),fe[e])throw new Error(`Method with name '${e}' is already defined.`);let n=typeof o=="function"?o:o.handler,r=typeof o=="function"?[]:o.permissions??[];fe[e]={type:t,name:e,handler:n,permissions:r};}async function bt(t,e,o){v();let n=fe[t];if(!n)throw new Error(`Method with name '${t}' is not defined.`);let{type:r,handler:i}=n,s=j$1("method",`method:${t}`,{type:r,args:e}),a;try{qe(o.roles,n.permissions),a=await i(e,o);}catch(l){throw s.end("error"),l}return s.end(),a}var Q=new y("_modelenceMigrations",{schema:{version:c.number(),appliedAt:c.date()},indexes:[{key:{version:1},unique:true}]});async function Ct(t){if(t.length===0)return;let e=t.map(({version:i})=>i),o=await Q.fetch({version:{$in:e}}),n=new Set(o.map(({version:i})=>i)),r=t.filter(({version:i})=>!n.has(i));if(r.length!==0){console.log(`Running migrations (${r.length})...`);for(let{version:i,description:s,handler:a}of r)console.log(`Running migration v${i}: ${s}`),await Q.insertOne({version:i,appliedAt:new Date}),await a(),console.log(`Migration v${i} complete`);}}var Et=new b("_system.migration",{stores:[Q]});var St=new b("_system.rateLimit",{stores:[q]});var xt=new b("_system.site",{configSchema:{url:{type:"string",isPublic:true,default:""}}});var we=class{async init(){this.config=await Io(),this.isDev()&&(console.log("Starting Vite dev server..."),this.viteServer=await createServer(this.config));}middlewares(){if(this.isDev())return this.viteServer?.middlewares??[];let e=[Ce.static("./.modelence/build/client".replace(/\\/g,"/"))];return this.config?.publicDir&&e.push(Ce.static(this.config.publicDir)),e}handler(e,o){if(this.isDev())try{o.sendFile("index.html",{root:"./src/client"});}catch(n){console.error("Error serving index.html:",n),o.status(500).send("Internal Server Error");}else o.sendFile("index.html",{root:"./.modelence/build/client".replace(/\\/g,"/")});}isDev(){return process.env.NODE_ENV!=="production"}};async function Oo(){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 To(t,e){let o=mergeConfig(t,e);if(o.plugins&&Array.isArray(o.plugins)){let n=new Set;o.plugins=o.plugins.flat().filter(r=>{if(!r||typeof r!="object"||Array.isArray(r))return true;let i=r.name;return !i||n.has(i)?false:(n.add(i),true)}).reverse(),o.plugins.reverse();}return o}async function Io(){let t=process.cwd(),e=await Oo(),o=[".eslintrc.js",".eslintrc.json",".eslintrc","eslint.config.js",".eslintrc.yml",".eslintrc.yaml"].find(i=>Ro.existsSync(ge.join(t,i))),n=[vo(),ko()];if(o){let i=(await import('vite-plugin-eslint')).default;n.push(i({failOnError:false,include:["src/**/*.js","src/**/*.jsx","src/**/*.ts","src/**/*.tsx"],cwd:t,overrideConfigFile:ge.resolve(t,o)}));}let r=defineConfig({plugins:n,build:{outDir:".modelence/build/client".replace(/\\/g,"/"),emptyOutDir:true},server:{middlewareMode:true},root:"./src/client",resolve:{alias:{"@":ge.resolve(t,"src").replace(/\\/g,"/")}}});return To(r,e)}function ko(){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 vt=new we;async function Rt(t,e){let{authToken:o}=await se(e);t.cookie("authToken",o,{httpOnly:true,secure:process.env.NODE_ENV==="production",sameSite:"strict"}),t.status(301),t.redirect("/");}function M(t,e){return `${t.protocol}://${t.get("host")}/api/_internal/auth/${e}/callback`}async function Y(t,e,o){let n=await m.findOne({[`authMethods.${o.providerName}.id`]:o.id}),{session:r,connectionInfo:i}=await ye(t);try{if(n){await Rt(e,n._id),h().onAfterLogin?.({user:n,session:r,connectionInfo:i}),h().login?.onSuccess?.(n);return}}catch(s){throw s instanceof Error&&(h().login?.onError?.(s),h().onLoginError?.({error:s,session:r,connectionInfo:i})),s}try{if(!o.email){e.status(400).json({error:`Email address is required for ${o.providerName} authentication.`});return}if(await m.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 m.insertOne({handle:o.email,emails:[{address:o.email,verified:o.emailVerified}],createdAt:new Date,authMethods:{[o.providerName]:{id:o.id}}});await Rt(e,a.insertedId);let l=await m.findOne({_id:a.insertedId},{readPreference:"primary"});l&&(h().onAfterSignup?.({user:l,session:r,connectionInfo:i}),h().signup?.onSuccess?.(l));}catch(s){throw s instanceof Error&&(h().onSignupError?.({error:s,session:r,connectionInfo:i}),h().signup?.onError?.(s)),s}}function X(t){return !t||typeof t!="string"?null:t}async function Ao(t,e,o,n){let r=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:n,grant_type:"authorization_code"})});if(!r.ok)throw new Error(`Failed to exchange code for token: ${r.statusText}`);return r.json()}async function Mo(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 Po(t,e){let o=X(t.query.code);if(!o){e.status(400).json({error:"Missing authorization code"});return}let n=String(a$1("_system.user.auth.google.clientId")),r=String(a$1("_system.user.auth.google.clientSecret")),i=M(t,"google");try{let s=await Ao(o,n,r,i),a=await Mo(s.access_token),l={id:a.id,email:a.email,emailVerified:a.verified_email,providerName:"google"};await Y(t,e,l);}catch(s){console.error("Google OAuth error:",s),e.status(500).json({error:"Authentication failed"});}}function Uo(){let t=Router(),e=(o,n,r)=>{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){n.status(503).json({error:"Google authentication is not configured"});return}r();};return t.get("/api/_internal/auth/google",e,(o,n)=>{let r=String(a$1("_system.user.auth.google.clientId")),i=M(o,"google"),s=new URL("https://accounts.google.com/o/oauth2/v2/auth");s.searchParams.append("client_id",r),s.searchParams.append("redirect_uri",i),s.searchParams.append("response_type","code"),s.searchParams.append("scope","profile email"),s.searchParams.append("access_type","online"),n.redirect(s.toString());}),t.get("/api/_internal/auth/google/callback",e,Po),t}var Ot=Uo;async function jo(t,e,o,n){let r=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:n})});if(!r.ok)throw new Error(`Failed to exchange code for token: ${r.statusText}`);return r.json()}async function $o(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 No(t,e){let o=X(t.query.code);if(!o){e.status(400).json({error:"Missing authorization code"});return}let n=String(a$1("_system.user.auth.github.clientId")),r=String(a$1("_system.user.auth.github.clientSecret")),i=M(t,"github");try{let s=await jo(o,n,r,i),a=await $o(s.access_token),l=a.email||"";if(!l){e.status(400).json({error:"Unable to retrieve email from GitHub. Please ensure your email is public or grant email permissions."});return}let p={id:String(a.id),email:l,emailVerified:!0,providerName:"github"};await Y(t,e,p);}catch(s){console.error("GitHub OAuth error:",s),e.status(500).json({error:"Authentication failed"});}}function qo(){let t=Router(),e=(o,n,r)=>{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){n.status(503).json({error:"GitHub authentication is not configured"});return}r();};return t.get("/api/_internal/auth/github",e,(o,n)=>{let r=String(a$1("_system.user.auth.github.clientId")),i=M(o,"github"),s=a$1("_system.user.auth.github.scopes"),a=s?String(s).split(",").map(p=>p.trim()).join(" "):"user:email",l=new URL("https://github.com/login/oauth/authorize");l.searchParams.append("client_id",r),l.searchParams.append("redirect_uri",i),l.searchParams.append("scope",a),n.redirect(l.toString());}),t.get("/api/_internal/auth/github/callback",e,No),t}var Tt=qo;function It(t){return async(e,o,n)=>{try{let r=await t({query:e.query,body:e.body,params:e.params,headers:e.headers,cookies:e.cookies,req:e,res:o,next:n});r&&(o.status(r.status||200),r.redirect&&o.redirect(r.redirect),r.headers&&Object.entries(r.headers).forEach(([i,s])=>{o.setHeader(i,s);}),o.send(r.data));}catch(r){r instanceof a$3?o.status(r.status).send(r.message):(console.error(`Error in route handler: ${e.path}`),console.error(r),o.status(500).send(String(r)));}}}var be=Object.freeze({});function kt(t){be=Object.freeze(Object.assign({},be,t));}function ee(){return be}function Bo(t,e){for(let o of e)for(let n of o.routes){let{path:r,handlers:i}=n;Object.entries(i).forEach(([s,a])=>{t[s](r,It(a));});}}async function Dt(t,{combinedModules:e,channels:o}){let n=Ce();n.use(Ce.json()),n.use(Ce.urlencoded({extended:true})),n.use(zo()),n.use(Ot()),n.use(Tt()),n.post("/api/_internal/method/:methodName(*)",async(a,l)=>{let{methodName:p}=a.params,C=await ye(a);try{let u=await bt(p,a.body.args,C);l.json({data:u,typeMap:a$2(u)});}catch(u){if(console.error(`Error in method ${p}:`,u),u instanceof a$3)l.status(u.status).send(u.message);else if(u instanceof Error&&u?.constructor?.name==="ZodError"&&"errors"in u){let T=u.flatten(),te=Object.entries(T.fieldErrors).map(([P,ne])=>`${P}: ${(ne??[]).join(", ")}`).join("; "),oe=T.formErrors.join("; "),F=[te,oe].filter(Boolean).join("; ");l.status(400).send(F);}else l.status(500).send(u instanceof Error?u.message:String(u));}}),Bo(n,e),await t.init(),t.middlewares&&n.use(t.middlewares()),n.all("*",(a,l)=>t.handler(a,l)),process.on("unhandledRejection",(a,l)=>{console.error("Unhandled Promise Rejection:"),console.error(a instanceof Error?a.stack:a),console.error("Promise:",l);}),process.on("uncaughtException",a=>{console.error("Uncaught Exception:"),console.error(a.stack),console.trace("Full application stack:");});let r=Fo.createServer(n),i=ee()?.provider;i&&i.init({httpServer:r,channels:o});let s=process.env.MODELENCE_PORT||process.env.PORT||3e3;r.listen(s,()=>{h$1("Application started",{source:"app"}),console.log(`
15
15
  Application started on http://localhost:${s}
16
- `);});}async function z(t){let e=x.string().nullish().transform(i=>i??null).parse(t.cookies.authToken||t.body.authToken),o=x.object({screenWidth:x.number(),screenHeight:x.number(),windowWidth:x.number(),windowHeight:x.number(),pixelRatio:x.number(),orientation:x.string().nullable()}).nullish().parse(t.body.clientInfo)??{screenWidth:0,screenHeight:0,windowWidth:0,windowHeight:0,pixelRatio:1,orientation:null},n={ip:zo(t),userAgent:t.get("user-agent"),acceptLanguage:t.get("accept-language"),referrer:t.get("referrer"),baseUrl:t.protocol+"://"+t.get("host")};if(!!$()){let{session:i,user:s,roles:a}=await j(e);return {clientInfo:o,connectionInfo:n,session:i,user:s,roles:a}}return {clientInfo:o,connectionInfo:n,session:null,user:null,roles:V()}}function zo(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 Vo({modules:t=[],roles:e$1={},defaultRoles:o={},server:n=xt,migrations:r=[],email:i={},auth:s={},websocket:a={}}){Mt.config(),Mt.config({path:".modelence.env"});let l=!!process.env.MODELENCE_SERVICE_ENDPOINT,d=process.env.MODELENCE_CRON_ENABLED==="true";rn().then(()=>{}).catch(()=>{});let E=[nt,Le,mt,Et,Ct],m=[...E,...t];e(),Go(E),Fo(t),je(e$1,o);let C=Yo(m);d$1(C);let O=Ko(m),ee=Zo(m);d&&Xo(m);let te=Qo(m);if(Xe(te),l){let{configs:A,environmentId:oe,appAlias:kt,environmentAlias:At,telemetry:Pt}=await rt({configSchema:C,cronJobsMetadata:d?dt():void 0,stores:O});c$1(A),f({environmentId:oe,appAlias:kt,environmentAlias:At,telemetry:Pt});}else c$1(nn(C));Je(i),Ge(s),It({...a,provider:a.provider||Be});let W=$();if(W&&(await qe(),en(O)),d&&await bt(r),W)for(let A of O)A.createIndexes();l&&(await g$1(),at()),d&&ut().catch(console.error),await Tt(n,{combinedModules:m,channels:ee});}function Fo(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))pe(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))pt(`${e.name}.${o}`,n);}}function Go(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))ft(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))ht(`${e.name}.${o}`,n);}}function Ko(t){return t.flatMap(e=>e.stores)}function Zo(t){return t.flatMap(e=>e.channels)}function Qo(t){return t.flatMap(e=>e.rateLimits)}function Yo(t){let e={};for(let o of t)for(let[n,r]of Object.entries(o.configSchema)){let i=`${o.name}.${n}`;if(i in e)throw new Error(`Duplicate config schema key: ${i} (${o.name})`);e[i]=r;}return e}function Xo(t){for(let e of t)for(let[o,n]of Object.entries(e.cronJobs))lt(`${e.name}.${o}`,n);}function en(t){let e=F();if(!e)throw new Error("Failed to initialize stores: MongoDB client not initialized");for(let o of t)o.init(e);}var tn={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",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 on(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 nn(t){let e=[];for(let[o,n]of Object.entries(tn)){let r=process.env[o],i=t[n];if(r){let s=i?.type??"string";e.push({key:n,type:s,value:on(r,s)});}}return e}async function rn(){if(process.env.MODELENCE_TRACKING_ENABLED!=="false"){let e=process.env.MODELENCE_SERVICE_ENDPOINT??"https://cloud.modelence.com",o=process.env.MODELENCE_ENVIRONMENT_ID,n=await sn(),r=await import('./package-VKQ3SMKC.js');await fetch(`${e}/api/track/app-start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:n.name,version:r.default.version,localHostname:mo.hostname(),environmentId:o})});}}async function sn(){try{let t=fe.join(process.cwd(),"package.json"),e=await Wo.readFile(t,"utf-8");return {name:JSON.parse(e).name||"unknown"}}catch{return {name:"unknown"}}}var Ee=class{constructor(e,o){this.category=e,this.canAccessChannel=o||null;}broadcast(e,o){let n=X().provider;if(!n){i("Websockets provider should be added to startApp",{});return}n.broadcast({category:this.category,id:e,data:o});}};function an(t){if(!g().provider)throw new Error("Email provider is not configured, see https://docs.modelence.com/email for more details.");return g().provider?.sendEmail(t)}
17
- export{w as Module,Ee as ServerChannel,y as Store,j as authenticate,R as consumeRateLimit,pe as createQuery,u as dbUsers,c as schema,an as sendEmail,Vo as startApp};//# sourceMappingURL=server.js.map
16
+ `);});}async function ye(t){let e=x.string().nullish().transform(i=>i??null).parse(t.cookies.authToken||t.body.authToken),o=x.object({screenWidth:x.number(),screenHeight:x.number(),windowWidth:x.number(),windowHeight:x.number(),pixelRatio:x.number(),orientation:x.string().nullable()}).nullish().parse(t.body.clientInfo)??{screenWidth:0,screenHeight:0,windowWidth:0,windowHeight:0,pixelRatio:1,orientation:null},n={ip:Wo(t),userAgent:t.get("user-agent"),acceptLanguage:t.get("accept-language"),referrer:t.get("referrer"),baseUrl:t.protocol+"://"+t.get("host")};if(!!$()){let{session:i,user:s,roles:a}=await j(e);return {clientInfo:o,connectionInfo:n,session:i,user:s,roles:a}}return {clientInfo:o,connectionInfo:n,session:null,user:null,roles:J()}}function Wo(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 Go({modules:t=[],roles:e$1={},defaultRoles:o={},server:n=vt,migrations:r=[],email:i={},auth:s={},websocket:a={}}){At.config(),At.config({path:".modelence.env"});let l=!!process.env.MODELENCE_SERVICE_ENDPOINT,p=process.env.MODELENCE_CRON_ENABLED==="true";an().then(()=>{}).catch(()=>{});let C=[rt,Le,pt,Et,St,xt],u=[...C,...t];e(),Zo(C),Ko(t),$e(e$1,o);let E=en(u);d$1(E);let T=Qo(u),te=Yo(u);p&&tn(u);let oe=Xo(u);if(et(oe),l){let{configs:P,environmentId:ne,appAlias:Mt,environmentAlias:Pt,telemetry:Ut}=await it({configSchema:E,cronJobsMetadata:p?mt():void 0,stores:T});c$1(P),f({environmentId:ne,appAlias:Mt,environmentAlias:Pt,telemetry:Ut});}else c$1(sn(E));Je(i),Ke(s),kt({...a,provider:a.provider||Fe});let F=$();if(F&&(await ze(),on(T)),p&&await Ct(r),F)for(let P of T)P.createIndexes();l&&(await g(),ct()),p&&dt().catch(console.error),await Dt(n,{combinedModules:u,channels:te});}function Ko(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))he(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))ft(`${e.name}.${o}`,n);}}function Zo(t){for(let e of t){for(let[o,n]of Object.entries(e.queries))ht(`${e.name}.${o}`,n);for(let[o,n]of Object.entries(e.mutations))gt(`${e.name}.${o}`,n);}}function Qo(t){return t.flatMap(e=>e.stores)}function Yo(t){return t.flatMap(e=>e.channels)}function Xo(t){return t.flatMap(e=>e.rateLimits)}function en(t){let e={};for(let o of t)for(let[n,r]of Object.entries(o.configSchema)){let i=`${o.name}.${n}`;if(i in e)throw new Error(`Duplicate config schema key: ${i} (${o.name})`);e[i]=r;}return e}function tn(t){for(let e of t)for(let[o,n]of Object.entries(e.cronJobs))ut(`${e.name}.${o}`,n);}function on(t){let e=H();if(!e)throw new Error("Failed to initialize stores: MongoDB client not initialized");for(let o of t)o.init(e);}var nn={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",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 rn(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 sn(t){let e=[];for(let[o,n]of Object.entries(nn)){let r=process.env[o],i=t[n];if(r){let s=i?.type??"string";e.push({key:n,type:s,value:rn(r,s)});}}return e}async function an(){if(process.env.MODELENCE_TRACKING_ENABLED!=="false"){let e=process.env.MODELENCE_SERVICE_ENDPOINT??"https://cloud.modelence.com",o=process.env.MODELENCE_ENVIRONMENT_ID,n=await cn(),r=await import('./package-ACF77X2N.js');await fetch(`${e}/api/track/app-start`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectName:n.name,version:r.default.version,localHostname:po.hostname(),environmentId:o})});}}async function cn(){try{let t=ge.join(process.cwd(),"package.json"),e=await Jo.readFile(t,"utf-8");return {name:JSON.parse(e).name||"unknown"}}catch{return {name:"unknown"}}}var Ee=class{constructor(e,o){this.category=e,this.canAccessChannel=o||null;}broadcast(e,o){let n=ee().provider;if(!n){i("Websockets provider should be added to startApp",{});return}n.broadcast({category:this.category,id:e,data:o});}};function ln(t){if(!w().provider)throw new Error("Email provider is not configured, see https://docs.modelence.com/email for more details.");return w().provider?.sendEmail(t)}
17
+ export{b as Module,Ee as ServerChannel,y as Store,j as authenticate,R as consumeRateLimit,he as createQuery,m as dbUsers,c as schema,ln as sendEmail,Go as startApp};//# sourceMappingURL=server.js.map
18
18
  //# sourceMappingURL=server.js.map