modelence 0.6.0-dev.1 → 0.6.0-dev.10
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/README.md +1 -1
- package/dist/bin/modelence.js +2 -2
- package/dist/bin/modelence.js.map +1 -1
- package/dist/chunk-C3UESBRX.js +2 -0
- package/dist/chunk-C3UESBRX.js.map +1 -0
- package/dist/chunk-EVITQL34.js +3 -0
- package/dist/chunk-EVITQL34.js.map +1 -0
- package/dist/client.d.ts +11 -11
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/package-HA5ZLHTV.js +2 -0
- package/dist/package-HA5ZLHTV.js.map +1 -0
- package/dist/server.d.ts +69 -12
- package/dist/server.js +10 -10
- package/dist/server.js.map +1 -1
- package/dist/types-B8cRKzII.d.ts +101 -0
- package/package.json +2 -1
- package/dist/chunk-5TLHWYXF.js +0 -2
- package/dist/chunk-5TLHWYXF.js.map +0 -1
- package/dist/package-ULFSXQ7D.js +0 -3
- package/dist/package-ULFSXQ7D.js.map +0 -1
- package/dist/serverRoom-Dn45ATJ4.d.ts +0 -31
- package/dist/types-B7qvJJOF.d.ts +0 -18
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Server } from 'http';
|
|
2
|
+
import { Document, ObjectId } from 'mongodb';
|
|
3
|
+
|
|
4
|
+
type ConfigType = 'text' | 'string' | 'number' | 'boolean' | 'secret';
|
|
5
|
+
type ConfigKey = string;
|
|
6
|
+
type ConfigParams = {
|
|
7
|
+
type: ConfigType;
|
|
8
|
+
default: ValueType<ConfigType>;
|
|
9
|
+
isPublic: boolean;
|
|
10
|
+
};
|
|
11
|
+
type AppConfig = {
|
|
12
|
+
key: ConfigKey;
|
|
13
|
+
value: ValueType<ConfigType>;
|
|
14
|
+
type: ConfigType;
|
|
15
|
+
};
|
|
16
|
+
type ConfigSchema = {
|
|
17
|
+
[key: string]: ConfigParams;
|
|
18
|
+
};
|
|
19
|
+
type ValueType<T> = T extends 'number' ? number : T extends 'string' ? string : T extends 'text' ? string : T extends 'boolean' ? boolean : T extends 'secret' ? string : never;
|
|
20
|
+
|
|
21
|
+
type User = Document;
|
|
22
|
+
type UserInfo = {
|
|
23
|
+
id: string;
|
|
24
|
+
handle: string;
|
|
25
|
+
};
|
|
26
|
+
type Role = string;
|
|
27
|
+
type Session = {
|
|
28
|
+
authToken: string;
|
|
29
|
+
expiresAt: Date;
|
|
30
|
+
userId: ObjectId | null;
|
|
31
|
+
};
|
|
32
|
+
type Permission = string;
|
|
33
|
+
type RoleDefinition = {
|
|
34
|
+
description?: string;
|
|
35
|
+
permissions: Permission[];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type canAccessChannel = (props: {
|
|
39
|
+
user: User | null;
|
|
40
|
+
session: Session | null;
|
|
41
|
+
roles: string[];
|
|
42
|
+
}) => Promise<boolean>;
|
|
43
|
+
declare class ServerChannel<T = any> {
|
|
44
|
+
readonly category: string;
|
|
45
|
+
readonly canAccessChannel: canAccessChannel | null;
|
|
46
|
+
constructor(category: string, canAccessChannel?: canAccessChannel);
|
|
47
|
+
broadcast(id: string, data: T): void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
declare class ClientChannel<T = any> {
|
|
51
|
+
readonly category: string;
|
|
52
|
+
private readonly onMessage;
|
|
53
|
+
constructor(category: string, onMessage: (data: T) => void);
|
|
54
|
+
init(): void;
|
|
55
|
+
joinChannel(id: string): void;
|
|
56
|
+
leaveChannel(id: string): void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface WebsocketServerProvider {
|
|
60
|
+
init(props: {
|
|
61
|
+
httpServer: Server;
|
|
62
|
+
channels: ServerChannel[];
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
broadcast<T>(props: {
|
|
65
|
+
category: string;
|
|
66
|
+
id: string;
|
|
67
|
+
data: T;
|
|
68
|
+
}): void;
|
|
69
|
+
}
|
|
70
|
+
interface WebsocketClientProvider {
|
|
71
|
+
init(props: {
|
|
72
|
+
channels?: ClientChannel[];
|
|
73
|
+
}): void;
|
|
74
|
+
on<T>(props: {
|
|
75
|
+
category: string;
|
|
76
|
+
listener: (data: T) => void;
|
|
77
|
+
}): void;
|
|
78
|
+
once<T>(props: {
|
|
79
|
+
category: string;
|
|
80
|
+
listener: (data: T) => void;
|
|
81
|
+
}): void;
|
|
82
|
+
off<T>(props: {
|
|
83
|
+
category: string;
|
|
84
|
+
listener: (data: T) => void;
|
|
85
|
+
}): void;
|
|
86
|
+
emit(props: {
|
|
87
|
+
eventName: string;
|
|
88
|
+
category: string;
|
|
89
|
+
id: string;
|
|
90
|
+
}): void;
|
|
91
|
+
joinChannel(props: {
|
|
92
|
+
category: string;
|
|
93
|
+
id: string;
|
|
94
|
+
}): void;
|
|
95
|
+
leaveChannel(props: {
|
|
96
|
+
category: string;
|
|
97
|
+
id: string;
|
|
98
|
+
}): void;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { type AppConfig as A, type ConfigSchema as C, type Permission as P, type RoleDefinition as R, type Session as S, type UserInfo as U, type WebsocketServerProvider as W, type WebsocketClientProvider as a, type ConfigKey as b, ClientChannel as c, ServerChannel as d, type User as e, type Role as f };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "modelence",
|
|
4
|
-
"version": "0.6.0-dev.
|
|
4
|
+
"version": "0.6.0-dev.10",
|
|
5
5
|
"description": "The Node.js Framework for Real-Time MongoDB Apps",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/global.d.ts",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@modelence/types": "^1.0.3",
|
|
57
|
+
"@socket.io/mongo-adapter": "^0.4.0",
|
|
57
58
|
"@vitejs/plugin-react": "^4.3.4",
|
|
58
59
|
"archiver": "^7.0.1",
|
|
59
60
|
"bcrypt": "^5.1.1",
|
package/dist/chunk-5TLHWYXF.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import {a as a$1}from'./chunk-R7MPLJMA.js';import {b,h as h$1}from'./chunk-2QLNYYBR.js';import {ObjectId}from'mongodb';import {z as z$1}from'zod';import {randomBytes}from'crypto';import {Server}from'socket.io';var d=class extends Error{},w=class extends d{constructor(t){super(t);this.status=401;this.name="AuthError";}},x=class extends d{constructor(t){super(t);this.status=400;this.name="ValidationError";}},D=class extends d{constructor(t){super(t);this.status=429;this.name="RateLimitError";}};var h=class{constructor(e,{stores:t=[],queries:n={},mutations:s={},routes:c=[],cronJobs:b={},configSchema:k={},rateLimits:A=[],rooms:j=[]}){this.name=e,this.stores=t,this.queries=n,this.mutations=s,this.routes=c,this.cronJobs=b,this.configSchema=k,this.rateLimits=A,this.rooms=j;}};var a=class{constructor(e,t){this.name=e,this.schema=t.schema,this.methods=t.methods,this.indexes=t.indexes;}getName(){return this.name}getSchema(){return this.schema}init(e){if(this.collection)throw new Error(`Collection ${this.name} is already initialized`);this.client=e,this.collection=this.client.db().collection(this.name);}async createIndexes(){this.indexes.length>0&&await this.requireCollection().createIndexes(this.indexes);}wrapDocument(e){return this.methods?Object.create(null,Object.getOwnPropertyDescriptors({...e,...this.methods})):e}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,t){let n=await this.requireCollection().findOne(e,t);return n?this.wrapDocument(n):null}async requireOne(e,t,n){let s=await this.findOne(e,t);if(!s)throw n?n():new Error(`Record not found in ${this.name}`);return s}find(e,t){let n=this.requireCollection().find(e);return t?.sort&&n.sort(t.sort),t?.limit&&n.limit(t.limit),t?.skip&&n.skip(t.skip),n}async findById(e){let t=typeof e=="string"?{_id:new ObjectId(e)}:{_id:e};return await this.findOne(t)}async requireById(e,t){let n=await this.findById(e);if(!n)throw t?t():new Error(`Record with id ${e} not found in ${this.name}`);return n}countDocuments(e){return this.requireCollection().countDocuments(e)}async fetch(e,t){return (await this.find(e,t).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,t){return await this.requireCollection().updateOne(this.getSelector(e),t)}async upsertOne(e,t){return await this.requireCollection().updateOne(this.getSelector(e),t,{upsert:true})}async updateMany(e,t,n){return await this.requireCollection().updateMany(e,t,n)}async upsertMany(e,t){return await this.requireCollection().updateMany(e,t,{upsert:true})}async deleteOne(e){return await this.requireCollection().deleteOne(e)}async deleteMany(e){return await this.requireCollection().deleteMany(e)}aggregate(e,t){return this.requireCollection().aggregate(e,t)}bulkWrite(e){return this.requireCollection().bulkWrite(e)}getDatabase(){return this.requireClient().db()}rawCollection(){return this.requireCollection()}async renameFrom(e,t){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,t);}};var v=z$1.string.bind(z$1),q=z$1.number.bind(z$1),P=z$1.date.bind(z$1),M=z$1.boolean.bind(z$1),F=z$1.array.bind(z$1),U=z$1.object.bind(z$1),z=z$1.enum.bind(z$1),o={string:v,number:q,date:P,boolean:M,array:F,object:U,enum:z,objectId(){return z$1.instanceof(ObjectId)},userId(){return z$1.instanceof(ObjectId)},ref(i){return z$1.instanceof(ObjectId)},union:z$1.union.bind(z$1),infer(i){return {}}};var T=new a("_modelenceUsers",{schema:{handle:o.string(),emails:o.array(o.object({address:o.string(),verified:o.boolean()})).optional(),createdAt:o.date(),authMethods:o.object({password:o.object({hash:o.string()}).optional(),google:o.object({id:o.string()}).optional()})},indexes:[{key:{handle:1},unique:true,collation:{locale:"en",strength:2}}]}),Se=new a("_modelenceDisposableEmailDomains",{schema:{domain:o.string(),addedAt:o.date()},indexes:[{key:{domain:1},unique:true}]}),we=new a("_modelenceEmailVerificationTokens",{schema:{userId:o.objectId(),email:o.string().optional(),token:o.string(),createdAt:o.date(),expiresAt:o.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]}),xe=new a("_modelenceResetPasswordTokens",{schema:{userId:o.objectId(),token:o.string(),createdAt:o.date(),expiresAt:o.date()},indexes:[{key:{token:1},unique:true},{key:{expiresAt:1},expireAfterSeconds:0}]});var l=new a("_modelenceSessions",{schema:{authToken:o.string(),createdAt:o.date(),expiresAt:o.date(),userId:o.userId().nullable()},indexes:[{key:{authToken:1},unique:true},{key:{expiresAt:1}}]});async function R(i){let e=i?await l.findOne({authToken:i}):null;return e?{authToken:String(e.authToken),expiresAt:new Date(e.expiresAt),userId:e.userId??null}:await $()}async function ke(i,e){await l.updateOne({authToken:i},{$set:{userId:e}});}async function Ae(i){await l.updateOne({authToken:i},{$set:{userId:null}});}async function $(i=null){let e=randomBytes(32).toString("base64url"),t=Date.now(),n=new Date(t+a$1.days(7));return await l.insertOne({authToken:e,createdAt:new Date(t),expiresAt:n,userId:i}),{authToken:e,expiresAt:n,userId:i}}async function K(i){let e=Date.now(),t=new Date(e+a$1.days(7));await l.updateOne({authToken:i.authToken},{$set:{lastActiveDate:new Date(e),expiresAt:t}});}var je=new h("_system.session",{stores:[l],mutations:{init:async function(i,{session:e,user:t}){return {session:e,user:t,configs:b()}},heartbeat:async function(i,{session:e}){e&&await K(e);}}});var I=new Map,u={authenticated:null,unauthenticated:null};function qe(i,e){u.authenticated=e.authenticated,u.unauthenticated=e.unauthenticated;for(let[t,n]of Object.entries(i))I.set(t,n);}function O(){return u.unauthenticated?[u.unauthenticated]:[]}function C(){return u.authenticated?[u.authenticated]:[]}function Pe(i,e){let t=e.find(n=>!B(i,n));if(t)throw new Error(`Access denied - missing permission: '${t}'`)}function B(i,e){for(let t of i){let n=I.get(t);if(n&&n.permissions.includes(e))return true}return false}async function _(i){let e=await R(i),t=e.userId?await T.findOne({_id:new ObjectId(e.userId)}):null,n=t?{id:t._id.toString(),handle:t.handle}:null,s=n?C():O();return {user:n,session:e,roles:s}}var m=null;function Je(i,e){return m=new Server(i,{cors:{origin:"*",methods:["GET","POST"]}}),m.use(async(t,n)=>{let s=t.handshake.auth.token;try{t.data=await _(s);}finally{n();}}),m.on("connection",t=>{h$1("Socket.IO client connected",{source:"websocket",socketId:t.id}),t.on("disconnect",()=>{h$1("Socket.IO client disconnected",{source:"websocket",socketId:t.id});}),t.on("joinRoom",async n=>{let[s]=n.split(":");for(let c of e)c.roomCategory===s&&(!c.canAccessRoom||await c.canAccessRoom(t.data))&&t.join(n);t.join(n),console.log(`User ${t.id} joined room ${n}`),t.emit("joinedRoom",n);}),t.on("leaveRoom",n=>{t.leave(n),console.log(`User ${t.id} left room ${n}`),t.emit("leftRoom",n);});}),h$1("Socket.IO server initialized",{source:"websocket"}),m}function Le(){return m}export{d as a,w as b,x as c,D as d,h as e,a as f,o as g,ke as h,Ae as i,$ as j,je as k,T as l,Se as m,we as n,xe as o,qe as p,O as q,Pe as r,_ as s,Je as t,Le as u};//# sourceMappingURL=chunk-5TLHWYXF.js.map
|
|
2
|
-
//# sourceMappingURL=chunk-5TLHWYXF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/error.ts","../src/app/module.ts","../src/data/store.ts","../src/data/types.ts","../src/auth/db.ts","../src/auth/session.ts","../src/auth/role.ts","../src/auth/index.ts","../src/socket/server.ts"],"names":["ModelenceError","AuthError","message","ValidationError","RateLimitError","Module","name","stores","queries","mutations","routes","cronJobs","configSchema","rateLimits","rooms","Store","options","client","document","selector","ObjectId","query","errorHandler","result","cursor","id","idSelector","documents","update","pipeline","operations","oldName","db","schemaString","z","schemaNumber","schemaDate","schemaBoolean","schemaArray","schemaObject","schemaEnum","schema","collection","usersCollection","dbDisposableEmailDomains","emailVerificationTokensCollection","resetPasswordTokensCollection","sessionsCollection","obtainSession","authToken","existingSession","createSession","setSessionUser","userId","clearSessionUser","randomBytes","now","expiresAt","time","processSessionHeartbeat","session","newExpiresAt","session_default","args","user","getPublicConfigs","roleMap","defaultRoles","initRoles","roles","_defaultRoles","definition","getUnauthenticatedRoles","getDefaultAuthenticatedRoles","requireAccess","requiredPermissions","missingPermission","permission","hasPermission","role","authenticate","userDoc","socketServer","initSocketServer","httpServer","SocketServer","socket","next","token","logInfo","roomName","roomCategory","room","getSocketServer"],"mappings":"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","file":"chunk-5TLHWYXF.js","sourcesContent":["export abstract class ModelenceError extends Error {\n abstract status: number;\n}\n\nexport class AuthError extends ModelenceError {\n status = 401;\n\n constructor(message: string) {\n super(message);\n this.name = 'AuthError';\n }\n}\n\nexport class ValidationError extends ModelenceError {\n status = 400;\n\n constructor(message: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class RateLimitError extends ModelenceError {\n status = 429;\n\n constructor(message: string) {\n super(message);\n this.name = 'RateLimitError';\n }\n}\n","import { ConfigSchema } from '../config/types';\nimport { CronJobInputParams } from '../cron/types';\nimport { Store } from '../data/store';\nimport { MethodDefinition } from '../methods/types';\nimport { RouteDefinition } from '../routes/types';\nimport { RateLimitRule } from '../rate-limit/types';\nimport { ServerRoom } from '@/socket/serverRoom';\n\n/** Array of Store instances that will be provisioned when the module is loaded */\ntype Stores = Store<any, any>[];\n\n/** Record of query methods that can be called from the client */\ntype Queries = Record<string, MethodDefinition<any>>;\n\n/** Record of mutation methods that can be called from the client */\ntype Mutations = Record<string, MethodDefinition<any>>;\n\n/**\n * The Module class is a core building block of a Modelence application that encapsulates related functionality.\n * Modules can contain stores, queries, mutations, routes, cron jobs and configurations.\n * \n * @category Module\n * \n * @example\n * ```ts\n * const todoModule = new Module('todo', {\n * stores: [dbTodos],\n * queries: {\n * async getAll() {\n * // Fetch and return all Todo items\n * }\n * },\n * mutations: {\n * async create({ title }, { user }) {\n * // Create a new Todo item\n * }\n * }\n * });\n * ```\n */\nexport class Module {\n /** @internal */\n public readonly name: string;\n\n /** @internal */\n public readonly stores: Stores;\n\n /** @internal */\n public readonly queries: Queries;\n\n /** @internal */\n public readonly mutations: Mutations;\n\n /** @internal */\n public readonly routes: RouteDefinition[];\n\n /** @internal */\n public readonly cronJobs: Record<string, CronJobInputParams>;\n\n /** @internal */\n public readonly configSchema: ConfigSchema;\n\n /** @internal */\n public readonly rateLimits: RateLimitRule[];\n\n /** @internal */\n public readonly rooms: ServerRoom[];\n\n /**\n * Creates a new Module instance\n * \n * @param name - The unique name of the module.\n * This name is used to namespace queries, mutations,\n * cron jobs and configuration values with a prefix (e.g. \"todo.create\")\n * \n * @param options - Module configuration options\n */\n constructor(\n name: string,\n { \n stores = [], \n queries = {}, \n mutations = {},\n routes = [],\n cronJobs = {},\n configSchema = {},\n rateLimits = [],\n rooms = []\n }: { \n stores?: Store<any, any>[],\n queries?: Queries,\n mutations?: Mutations,\n routes?: RouteDefinition[],\n cronJobs?: Record<string, CronJobInputParams>,\n configSchema?: ConfigSchema,\n rateLimits?: RateLimitRule[],\n rooms?: ServerRoom[],\n }\n ) {\n this.name = name;\n this.stores = stores;\n this.queries = queries;\n this.mutations = mutations;\n this.routes = routes;\n this.cronJobs = cronJobs;\n this.configSchema = configSchema;\n this.rateLimits = rateLimits;\n this.rooms = rooms;\n }\n}\n","import {\n AggregateOptions,\n AggregationCursor,\n Collection,\n DeleteResult,\n Document,\n IndexDescription,\n InsertOneResult,\n MongoClient,\n UpdateResult,\n Filter,\n WithId,\n OptionalUnlessRequiredId,\n FindOptions,\n UpdateFilter,\n ObjectId,\n BulkWriteResult,\n AnyBulkWriteOperation,\n InsertManyResult,\n Db,\n ClientSession,\n} from 'mongodb';\n\nimport { ModelSchema, InferDocumentType } from './types';\n\n/**\n * The Store class provides a type-safe interface for MongoDB collections with built-in schema validation and helper methods.\n * \n * @category Store\n * @typeParam TSchema - The document schema type\n * @typeParam TMethods - Custom methods that will be added to documents\n * \n * @example\n * ```ts\n * const dbTodos = new Store('todos', {\n * schema: {\n * title: schema.string(),\n * completed: schema.boolean(),\n * dueDate: schema.date().optional(),\n * userId: schema.userId(),\n * },\n * methods: {\n * isOverdue() {\n * return this.dueDate < new Date();\n * }\n * }\n * });\n * ```\n */\nexport class Store<\n TSchema extends ModelSchema,\n TMethods extends Record<string, (this: WithId<InferDocumentType<TSchema>> & TMethods, ...args: Parameters<any>) => any>\n> {\n /** @internal */\n readonly _type!: InferDocumentType<TSchema>;\n /** @internal */\n readonly _rawDoc!: WithId<this['_type']>;\n /** @internal */\n readonly _doc!: this['_rawDoc'] & TMethods;\n \n readonly Doc!: this['_doc'];\n\n private name: string;\n private readonly schema: TSchema;\n private readonly methods?: TMethods;\n private readonly indexes: IndexDescription[];\n private collection?: Collection<this['_type']>;\n private client?: MongoClient;\n\n /**\n * Creates a new Store instance\n * \n * @param name - The collection name in MongoDB\n * @param options - Store configuration\n */\n constructor(\n name: string,\n options: {\n /** Document schema using Modelence schema types */\n schema: TSchema;\n /** Custom methods to add to documents */\n methods?: TMethods;\n /** MongoDB indexes to create */\n indexes: IndexDescription[];\n }\n ) {\n this.name = name;\n this.schema = options.schema;\n this.methods = options.methods;\n this.indexes = options.indexes;\n }\n\n getName() {\n return this.name;\n }\n\n /** @internal */\n getSchema() {\n return this.schema;\n }\n\n /** @internal */\n init(client: MongoClient) {\n if (this.collection) {\n throw new Error(`Collection ${this.name} is already initialized`);\n }\n\n this.client = client;\n this.collection = this.client.db().collection<this['_type']>(this.name);\n }\n\n /** @internal */\n async createIndexes() {\n if (this.indexes.length > 0) {\n await this.requireCollection().createIndexes(this.indexes);\n }\n }\n\n private wrapDocument(document: this['_rawDoc']): this['_doc'] {\n if (!this.methods) {\n return document as unknown as this['_doc'];\n }\n\n const result = Object.create(\n null,\n Object.getOwnPropertyDescriptors({\n ...document,\n ...this.methods\n })\n );\n\n return result as this['_doc'];\n }\n\n /**\n * For convenience, to also allow directy passing a string or ObjectId as the selector\n */\n private getSelector(selector: Filter<this['_type']> | string | ObjectId) {\n if (typeof selector === 'string') {\n return { _id: new ObjectId(selector) } as Filter<this['_type']>;\n }\n\n if (selector instanceof ObjectId) {\n return { _id: selector } as Filter<this['_type']>;\n }\n\n return selector;\n }\n\n /** @internal */\n requireCollection() {\n if (!this.collection) {\n throw new Error(`Collection ${this.name} is not provisioned`);\n }\n\n return this.collection;\n }\n\n /** @internal */\n requireClient() {\n if (!this.client) {\n throw new Error(`Database is not connected`);\n }\n\n return this.client;\n }\n\n async findOne(\n query: Filter<this['_type']>, \n options?: FindOptions\n ) {\n const document = await this.requireCollection().findOne<this['_rawDoc']>(query, options);\n return document ? this.wrapDocument(document) : null;\n }\n\n async requireOne(\n query: Filter<this['_type']>, \n options?: FindOptions,\n errorHandler?: () => Error\n ): Promise<this['_doc']> {\n \n const result = await this.findOne(query, options);\n if (!result) {\n throw errorHandler ? errorHandler() : new Error(`Record not found in ${this.name}`);\n }\n return result;\n }\n\n private find(query: Filter<this['_type']>, options?: { sort?: Document, limit?: number, skip?: number }) {\n const cursor = this.requireCollection().find(query);\n if (options?.sort) {\n cursor.sort(options.sort);\n }\n if (options?.limit) {\n cursor.limit(options.limit);\n }\n if (options?.skip) {\n cursor.skip(options.skip);\n }\n return cursor;\n }\n\n /**\n * Fetches a single document by its ID\n * \n * @param id - The ID of the document to find\n * @returns The document, or null if not found\n */\n async findById(id: string | ObjectId): Promise<this['_doc'] | null> {\n const idSelector = typeof id === 'string' ? { _id: new ObjectId(id) } : { _id: id };\n return await this.findOne(idSelector as Filter<this['_type']>);\n }\n\n /**\n * Fetches a single document by its ID, or throws an error if not found\n * \n * @param id - The ID of the document to find\n * @param errorHandler - Optional error handler to return a custom error if the document is not found\n * @returns The document\n */\n async requireById(id: string | ObjectId, errorHandler?: () => Error): Promise<this['_doc']> {\n const result = await this.findById(id);\n if (!result) {\n throw errorHandler ? errorHandler() : new Error(`Record with id ${id} not found in ${this.name}`);\n }\n return result;\n }\n\n /**\n * Counts the number of documents that match a query\n * \n * @param query - The query to filter documents\n * @returns The number of documents that match the query\n */\n countDocuments(query: Filter<this['_type']>): Promise<number> {\n return this.requireCollection().countDocuments(query);\n }\n\n /**\n * Fetches multiple documents, equivalent to Node.js MongoDB driver's `find` and `toArray` methods combined.\n * \n * @param query - The query to filter documents\n * @param options - Options\n * @returns The documents\n */\n async fetch(query: Filter<this['_type']>, options?: { sort?: Document, limit?: number, skip?: number }): Promise<this['_doc'][]> {\n const cursor = this.find(query, options)\n return (await cursor.toArray()).map(this.wrapDocument.bind(this));\n }\n\n /**\n * Inserts a single document\n * \n * @param document - The document to insert\n * @returns The result of the insert operation\n */\n async insertOne(document: OptionalUnlessRequiredId<this['_type']>): Promise<InsertOneResult> {\n return await this.requireCollection().insertOne(document);\n }\n\n /**\n * Inserts multiple documents\n * \n * @param documents - The documents to insert\n * @returns The result of the insert operation\n */\n async insertMany(documents: OptionalUnlessRequiredId<this['_type']>[]): Promise<InsertManyResult> {\n return await this.requireCollection().insertMany(documents);\n }\n\n /**\n * Updates a single document\n * \n * @param selector - The selector to find the document to update\n * @param update - The update to apply to the document\n * @returns The result of the update operation\n */\n async updateOne(selector: Filter<this['_type']> | string | ObjectId, update: UpdateFilter<this['_type']>): Promise<UpdateResult> {\n return await this.requireCollection().updateOne(this.getSelector(selector), update);\n }\n\n /**\n * Updates a single document, or inserts it if it doesn't exist\n * \n * @param selector - The selector to find the document to update\n * @param update - The MongoDB modifier to apply to the document\n * @returns The result of the update operation\n */\n async upsertOne(selector: Filter<this['_type']> | string | ObjectId, update: UpdateFilter<this['_type']>): Promise<UpdateResult> {\n return await this.requireCollection().updateOne(this.getSelector(selector), update, { upsert: true });\n }\n\n /**\n * Updates multiple documents\n * \n * @param selector - The selector to find the documents to update\n * @param update - The MongoDB modifier to apply to the documents\n * @returns The result of the update operation\n */\n async updateMany(\n selector: Filter<this['_type']>, \n update: UpdateFilter<this['_type']>, \n options?: { session?: ClientSession }\n ): Promise<UpdateResult> {\n return await this.requireCollection().updateMany(selector, update, options);\n }\n\n /**\n * Updates multiple documents, or inserts them if they don't exist\n * \n * @param selector - The selector to find the documents to update\n * @param update - The MongoDB modifier to apply to the documents\n * @returns The result of the update operation\n */\n async upsertMany(selector: Filter<this['_type']>, update: UpdateFilter<this['_type']>): Promise<UpdateResult> {\n return await this.requireCollection().updateMany(selector, update, { upsert: true });\n }\n\n /**\n * Deletes a single document\n * \n * @param selector - The selector to find the document to delete\n * @returns The result of the delete operation\n */\n async deleteOne(selector: Filter<this['_type']>): Promise<DeleteResult> {\n return await this.requireCollection().deleteOne(selector);\n }\n\n /**\n * Deletes multiple documents\n * \n * @param selector - The selector to find the documents to delete\n * @returns The result of the delete operation\n */\n async deleteMany(selector: Filter<this['_type']>): Promise<DeleteResult> {\n return await this.requireCollection().deleteMany(selector);\n }\n\n /**\n * Aggregates documents using MongoDB's aggregation framework\n * \n * @param pipeline - The aggregation pipeline\n * @param options - Optional options\n * @returns The aggregation cursor\n */\n aggregate(pipeline: Document[], options?: AggregateOptions): AggregationCursor<Document> {\n return this.requireCollection().aggregate(pipeline, options);\n }\n\n /**\n * Performs a bulk write operation on the collection\n * \n * @param operations - The operations to perform\n * @returns The result of the bulk write operation\n */\n bulkWrite(operations: AnyBulkWriteOperation<this['_type']>[]): Promise<BulkWriteResult> {\n return this.requireCollection().bulkWrite(operations);\n }\n\n /**\n * Returns the raw MongoDB database instance for advanced operations\n * @returns The MongoDB database instance\n * @throws Error if the store is not provisioned\n */\n getDatabase() {\n return this.requireClient().db();\n }\n\n /**\n * Returns the raw MongoDB collection instance for advanced operations\n * @returns The MongoDB collection instance\n * @throws Error if the store is not provisioned\n */\n rawCollection() {\n return this.requireCollection();\n }\n\n /**\n * Renames an existing collection to this store's name, used for migrations\n * @param oldName - The previous name of the collection\n * @throws Error if the old collection doesn't exist or if this store's collection already exists\n */\n async renameFrom(oldName: string, options?: { session?: ClientSession }) {\n const db = this.getDatabase();\n\n if (!this.collection || !db) {\n throw new Error(`Store ${this.name} is not provisioned`);\n }\n\n const oldCollections = await db.listCollections({ name: oldName }).toArray();\n if (oldCollections.length === 0) {\n throw new Error(`Collection ${oldName} not found`);\n }\n\n const newCollections = await db.listCollections({ name: this.name }).toArray();\n if (newCollections.length > 0) {\n throw new Error(`Collection ${this.name} already exists`);\n }\n\n const existingCollection = db.collection<this['_type']>(oldName);\n\n await existingCollection.rename(this.name, options);\n }\n}\n","import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { Store } from './store';\n\ntype ObjectTypeDefinition = {\n [key: string]: SchemaTypeDefinition;\n};\n\ntype SingularSchemaTypeDefinition = z.ZodType | ObjectTypeDefinition; // ReturnType<typeof schema[keyof typeof schema]>;\n\ntype SchemaTypeDefinition = SingularSchemaTypeDefinition | Array<SingularSchemaTypeDefinition>;\n\nexport type ModelSchema = {\n [key: string]: SchemaTypeDefinition;\n};\n\nconst schemaString: typeof z.string = z.string.bind(z);\n\nconst schemaNumber: typeof z.number = z.number.bind(z);\n\nconst schemaDate: typeof z.date = z.date.bind(z);\n\nconst schemaBoolean: typeof z.boolean = z.boolean.bind(z);\n\nconst schemaArray: typeof z.array = z.array.bind(z);\n\nconst schemaObject: typeof z.object = z.object.bind(z);\n\nconst schemaEnum: typeof z.enum = z.enum.bind(z);\n\nexport const schema = {\n string: schemaString,\n number: schemaNumber,\n date: schemaDate,\n boolean: schemaBoolean,\n array: schemaArray,\n object: schemaObject,\n enum: schemaEnum,\n objectId(): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId);\n },\n userId(): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId);\n },\n ref(collection: string | Store<any, any>): z.ZodType<ObjectId> {\n return z.instanceof(ObjectId);\n },\n union: z.union.bind(z),\n infer<T extends SchemaTypeDefinition>(schema: T): InferDocumentType<T> {\n return {} as InferDocumentType<T>;\n }\n} as const;\n\nexport type InferDocumentType<T extends SchemaTypeDefinition> = {\n [K in keyof T as T[K] extends z.ZodOptional<any> ? K : never]?: (T[K] extends z.ZodType ? z.infer<T[K]> : never);\n} & {\n [K in keyof T as T[K] extends z.ZodOptional<any> ? never : K]:\n T[K] extends z.ZodType ? z.infer<T[K]> :\n T[K] extends Array<infer ElementType extends SchemaTypeDefinition> ? Array<InferDocumentType<ElementType>> :\n T[K] extends ObjectTypeDefinition ? InferDocumentType<T[K]> :\n never;\n};\n\nexport namespace schema {\n export type infer<T extends SchemaTypeDefinition> = InferDocumentType<T>;\n}\n","import { schema } from '../data/types';\nimport { Store } from '../data/store';\n\n/**\n * Database collection for storing user accounts with authentication methods and profile information.\n * \n * This is where **signupWithPassword** automatically creates new users.\n * \n * @example\n * ```typescript\n * // Find user by email\n * const user = await dbUsers.findOne(\n * { 'emails.address': 'john@example.com' }\n * );\n * ```\n * \n */\nexport const usersCollection = new Store('_modelenceUsers', {\n schema: {\n handle: schema.string(),\n emails: schema.array(schema.object({\n address: schema.string(),\n verified: schema.boolean(),\n })).optional(),\n createdAt: schema.date(),\n authMethods: schema.object({\n password: schema.object({\n hash: schema.string(),\n }).optional(),\n google: schema.object({\n id: schema.string(),\n }).optional(),\n }),\n },\n indexes: [\n {\n key: { handle: 1 },\n unique: true,\n collation: { locale: 'en', strength: 2 } // Case-insensitive\n },\n ]\n});\n\nexport const dbDisposableEmailDomains = new Store('_modelenceDisposableEmailDomains', {\n schema: {\n domain: schema.string(),\n addedAt: schema.date(),\n },\n indexes: [\n {\n key: { domain: 1 },\n unique: true\n }\n ]\n});\n\nexport const emailVerificationTokensCollection = new Store('_modelenceEmailVerificationTokens', {\n schema: {\n userId: schema.objectId(),\n email: schema.string().optional(),\n token: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n },\n indexes: [\n {\n key: { token: 1 },\n unique: true\n },\n {\n key: { expiresAt: 1 },\n expireAfterSeconds: 0\n }\n ]\n});\n\nexport const resetPasswordTokensCollection = new Store('_modelenceResetPasswordTokens', {\n schema: {\n userId: schema.objectId(),\n token: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n },\n indexes: [\n {\n key: { token: 1 },\n unique: true\n },\n {\n key: { expiresAt: 1 },\n expireAfterSeconds: 0\n }\n ]\n});\n","import { randomBytes } from 'crypto';\nimport { ObjectId } from 'mongodb';\nimport { Module } from '../app/module';\nimport { getPublicConfigs } from '../config/server';\nimport { Store } from '../data/store';\nimport { schema } from '../data/types';\nimport { time } from '../time';\nimport { Session } from './types';\n\nexport const sessionsCollection = new Store('_modelenceSessions', {\n schema: {\n authToken: schema.string(),\n createdAt: schema.date(),\n expiresAt: schema.date(),\n userId: schema.userId().nullable(),\n },\n indexes: [\n { key: { authToken: 1 }, unique: true },\n { key: { expiresAt: 1 }},\n ]\n // TODO: add TTL index on expiresAt\n});\n\nexport async function obtainSession(authToken: string | null): Promise<Session> {\n const existingSession = authToken ? await sessionsCollection.findOne({ authToken }) : null;\n\n if (existingSession) {\n return {\n authToken: String(existingSession.authToken),\n expiresAt: new Date(existingSession.expiresAt),\n userId: existingSession.userId ?? null,\n }\n }\n\n return await createSession();\n}\n\nexport async function setSessionUser(authToken: string, userId: ObjectId) {\n await sessionsCollection.updateOne({ authToken }, {\n $set: { userId }\n });\n}\n\nexport async function clearSessionUser(authToken: string) {\n await sessionsCollection.updateOne({ authToken }, {\n $set: { userId: null }\n });\n}\n\nexport async function createSession(userId: ObjectId | null = null): Promise<Session> {\n // TODO: add rate-limiting and captcha handling\n\n const authToken = randomBytes(32).toString('base64url');\n const now = Date.now();\n const expiresAt = new Date(now + time.days(7));\n\n await sessionsCollection.insertOne({\n authToken,\n createdAt: new Date(now),\n expiresAt,\n userId,\n });\n\n return {\n authToken,\n expiresAt,\n userId,\n };\n}\n\nasync function processSessionHeartbeat(session: Session) {\n const now = Date.now();\n const newExpiresAt = new Date(now + time.days(7));\n\n await sessionsCollection.updateOne({ authToken: session.authToken }, {\n $set: {\n lastActiveDate: new Date(now),\n expiresAt: newExpiresAt\n }\n });\n}\n\nexport default new Module('_system.session', {\n stores: [sessionsCollection],\n mutations: {\n init: async function(args, { session, user }) {\n // TODO: mark or track app load somewhere\n \n return {\n session,\n user,\n configs: getPublicConfigs(),\n };\n },\n heartbeat: async function(args, { session }) {\n // Session might not exist if there is no database/authentication setup\n if (session) {\n await processSessionHeartbeat(session);\n }\n }\n },\n});\n","import { RoleDefinition, Role, DefaultRoles, Permission } from './types';\n\nconst roleMap = new Map<Role, RoleDefinition>();\nconst defaultRoles: DefaultRoles = {\n authenticated: null,\n unauthenticated: null,\n};\n\nexport function initRoles(roles: Record<Role, RoleDefinition>, _defaultRoles: Record<string, Role>) {\n defaultRoles.authenticated = _defaultRoles.authenticated;\n defaultRoles.unauthenticated = _defaultRoles.unauthenticated;\n\n for (const [name, definition] of Object.entries(roles)) {\n roleMap.set(name, definition);\n }\n}\n\nexport function getUnauthenticatedRoles() {\n return defaultRoles.unauthenticated ? [defaultRoles.unauthenticated] : [];\n}\n\nexport function getDefaultAuthenticatedRoles() {\n return defaultRoles.authenticated ? [defaultRoles.authenticated] : [];\n}\n\nexport function hasAccess(roles: Role[], requiredPermissions: Permission[]) {\n return requiredPermissions.every(permission => hasPermission(roles, permission));\n}\n\nexport function requireAccess(roles: Role[], requiredPermissions: Permission[]) {\n const missingPermission = requiredPermissions.find(permission => !hasPermission(roles, permission));\n\n if (missingPermission) {\n throw new Error(`Access denied - missing permission: '${missingPermission}'`);\n }\n}\n\nexport function hasPermission(roles: Role[], permission: Permission) {\n for (const role of roles) {\n const definition = roleMap.get(role);\n\n if (definition && definition.permissions.includes(permission)) {\n return true;\n }\n }\n\n return false;\n}\n","import { ObjectId } from 'mongodb';\n\nimport { obtainSession } from './session';\nimport { usersCollection } from './db';\nimport { getDefaultAuthenticatedRoles, getUnauthenticatedRoles } from './role';\nimport { Role, Session, UserInfo } from './types';\n\nexport async function authenticate(authToken: string | null): Promise<{ session: Session, user: UserInfo | null, roles: Role[] }> {\n const session = await obtainSession(authToken);\n\n const userDoc = session.userId ? await usersCollection.findOne({ _id: new ObjectId(session.userId) }) : null;\n const user = userDoc ? {\n id: userDoc._id.toString(),\n handle: userDoc.handle,\n } : null;\n\n const roles = user ? getDefaultAuthenticatedRoles() : getUnauthenticatedRoles();\n\n return {\n user,\n session,\n roles,\n };\n}\n","import { Server as SocketServer, Socket } from 'socket.io';\nimport { logInfo } from '../telemetry';\nimport { authenticate } from '@/auth';\nimport type { ServerRoom } from './serverRoom';\nimport type { Server } from 'http';\n\nlet socketServer: SocketServer | null = null;\n\nexport function initSocketServer(\n httpServer: Server,\n rooms: ServerRoom[],\n) {\n socketServer = new SocketServer(httpServer, {\n cors: {\n origin: \"*\",\n methods: [\"GET\", \"POST\"]\n }\n });\n\n socketServer.use(async (socket, next) => {\n const token = socket.handshake.auth.token;\n\n try {\n socket.data = await authenticate(token);\n } finally {\n next();\n }\n });\n\n socketServer.on('connection', (socket: Socket) => {\n logInfo(`Socket.IO client connected`, { source: 'websocket', socketId: socket.id });\n \n socket.on('disconnect', () => {\n logInfo(`Socket.IO client disconnected`, { source: 'websocket', socketId: socket.id });\n });\n\n socket.on('joinRoom', async (roomName) => {\n const [roomCategory] = roomName.split(':');\n for (const room of rooms) {\n if (\n room.roomCategory === roomCategory &&\n (\n !room.canAccessRoom ||\n await room.canAccessRoom(socket.data)\n )\n ) {\n socket.join(roomName);\n }\n }\n\n socket.join(roomName);\n console.log(`User ${socket.id} joined room ${roomName}`);\n socket.emit('joinedRoom', roomName);\n });\n\n socket.on('leaveRoom', (roomName) => {\n socket.leave(roomName);\n console.log(`User ${socket.id} left room ${roomName}`);\n socket.emit('leftRoom', roomName);\n });\n });\n\n logInfo(`Socket.IO server initialized`, { source: 'websocket' });\n\n return socketServer;\n}\n\nexport function getSocketServer() {\n return socketServer;\n}\n"]}
|
package/dist/package-ULFSXQ7D.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
var s="module",i="modelence",o="0.6.0-dev.1",p="The Node.js Framework for Real-Time MongoDB Apps",r="dist/index.js",n="dist/global.d.ts",c={".":"./dist/index.js","./client":"./dist/client.js","./server":"./dist/server.js","./telemetry":"./dist/telemetry.js","./mongodb":"./dist/mongo.js"},d=["dist","dist/bin"],l={modelence:"./dist/bin/modelence.js"},a={build:"tsup",dev:"tsup --watch",prepublishOnly:"npm run build",test:'echo "Error: no test specified" && exit 1',postversion:"git push && git push --tags"},m={type:"git",url:"git+https://github.com/modelence/modelence.git"},u="Modelence",y="SEE LICENSE IN LICENSE",g={url:"https://github.com/modelence/modelence/issues"},h="https://modelence.com",b={"@types/archiver":"^6.0.3","@types/bcrypt":"^5.0.2","@types/cookie-parser":"^1.4.9","@types/express":"^5.0.0","@types/fs-extra":"^11.0.4","@types/node":"^22.5.1","@types/passport-google-oauth20":"^2.0.16","@types/react":"^19.0.0","@types/react-dom":"^19.0.1","@types/socket.io":"^3.0.1","@typescript-eslint/eslint-plugin":"^8.17.0","@typescript-eslint/parser":"^8.17.0",react:"^19.0.0","react-dom":"^19.0.0"},v={"@modelence/types":"^1.0.3","@vitejs/plugin-react":"^4.3.4",archiver:"^7.0.1",bcrypt:"^5.1.1",commander:"^12.0.0","cookie-parser":"^1.4.7",dotenv:"^16.4.5","elastic-apm-node":"^4.8.0",express:"^4.21.0","fs-extra":"^11.2.0",jiti:"^2.4.2",mongodb:"^6.8.1",open:"^10.1.0",passport:"^0.7.0","passport-google-oauth20":"^2.0.0","socket.io":"^4.8.1","socket.io-client":"^4.8.1",tsup:"^8.3.6",tsx:"^4.19.3",typescript:"^5.7.2",vite:"^6.0.3","vite-plugin-eslint":"^1.8.1",winston:"^3.15.0","winston-elasticsearch":"^0.19.0",zod:"^3.23.8",zustand:"^5.0.2"},j={react:">=18.0.0","react-dom":">=18.0.0"},x={type:s,name:i,version:o,description:p,main:r,types:n,exports:c,files:d,bin:l,scripts:a,repository:m,author:u,license:y,bugs:g,homepage:h,devDependencies:b,dependencies:v,peerDependencies:j};
|
|
2
|
-
export{u as author,l as bin,g as bugs,x as default,v as dependencies,p as description,b as devDependencies,c as exports,d as files,h as homepage,y as license,r as main,i as name,j as peerDependencies,m as repository,a as scripts,s as type,n as types,o as version};//# sourceMappingURL=package-ULFSXQ7D.js.map
|
|
3
|
-
//# sourceMappingURL=package-ULFSXQ7D.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json"],"names":["type","name","version","description","main","types","exports","files","bin","scripts","repository","author","license","bugs","homepage","devDependencies","dependencies","peerDependencies","package_default"],"mappings":"AACE,IAAAA,CAAAA,CAAQ,SACRC,CAAAA,CAAQ,WAAA,CACRC,EAAW,aAAA,CACXC,CAAAA,CAAe,mDACfC,CAAAA,CAAQ,eAAA,CACRC,EAAS,kBAAA,CACTC,CAAAA,CAAW,CACT,GAAA,CAAK,iBAAA,CACL,WAAY,kBAAA,CACZ,UAAA,CAAY,kBAAA,CACZ,aAAA,CAAe,qBAAA,CACf,WAAA,CAAa,iBACf,CAAA,CACAC,CAAAA,CAAS,CACP,MAAA,CACA,UACF,EACAC,CAAAA,CAAO,CACL,UAAa,yBACf,CAAA,CACAC,EAAW,CACT,KAAA,CAAS,OACT,GAAA,CAAO,cAAA,CACP,eAAkB,eAAA,CAClB,IAAA,CAAQ,2CAAA,CACR,WAAA,CAAe,6BACjB,CAAA,CACAC,EAAc,CACZ,IAAA,CAAQ,MACR,GAAA,CAAO,gDACT,EACAC,CAAAA,CAAU,WAAA,CACVC,EAAW,wBAAA,CACXC,CAAAA,CAAQ,CACN,GAAA,CAAO,+CACT,EACAC,CAAAA,CAAY,uBAAA,CACZC,EAAmB,CACjB,iBAAA,CAAmB,QAAA,CACnB,eAAA,CAAiB,QAAA,CACjB,sBAAA,CAAwB,SACxB,gBAAA,CAAkB,QAAA,CAClB,kBAAmB,SAAA,CACnB,aAAA,CAAe,UACf,gCAAA,CAAkC,SAAA,CAClC,eAAgB,SAAA,CAChB,kBAAA,CAAoB,UACpB,kBAAA,CAAoB,QAAA,CACpB,mCAAoC,SAAA,CACpC,2BAAA,CAA6B,UAC7B,KAAA,CAAS,SAAA,CACT,WAAA,CAAa,SACf,CAAA,CACAC,CAAAA,CAAgB,CACd,kBAAA,CAAoB,QAAA,CACpB,uBAAwB,QAAA,CACxB,QAAA,CAAY,SACZ,MAAA,CAAU,QAAA,CACV,UAAa,SAAA,CACb,eAAA,CAAiB,SACjB,MAAA,CAAU,SAAA,CACV,mBAAoB,QAAA,CACpB,OAAA,CAAW,UACX,UAAA,CAAY,SAAA,CACZ,IAAA,CAAQ,QAAA,CACR,OAAA,CAAW,QAAA,CACX,KAAQ,SAAA,CACR,QAAA,CAAY,SACZ,yBAAA,CAA2B,QAAA,CAC3B,YAAa,QAAA,CACb,kBAAA,CAAoB,SACpB,IAAA,CAAQ,QAAA,CACR,IAAO,SAAA,CACP,UAAA,CAAc,SACd,IAAA,CAAQ,QAAA,CACR,qBAAsB,QAAA,CACtB,OAAA,CAAW,SAAA,CACX,uBAAA,CAAyB,SAAA,CACzB,GAAA,CAAO,UACP,OAAA,CAAW,QACb,EACAC,CAAAA,CAAoB,CAClB,MAAS,UAAA,CACT,WAAA,CAAa,UACf,CAAA,CArFFC,CAAAA,CAAA,CACE,IAAA,CAAAlB,CAAAA,CACA,KAAAC,CAAAA,CACA,OAAA,CAAAC,EACA,WAAA,CAAAC,CAAAA,CACA,IAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CACA,QAAAC,CAAAA,CAOA,KAAA,CAAAC,EAIA,GAAA,CAAAC,CAAAA,CAGA,QAAAC,CAAAA,CAOA,UAAA,CAAAC,EAIA,MAAA,CAAAC,CAAAA,CACA,QAAAC,CAAAA,CACA,IAAA,CAAAC,EAGA,QAAA,CAAAC,CAAAA,CACA,gBAAAC,CAAAA,CAgBA,YAAA,CAAAC,CAAAA,CA4BA,gBAAA,CAAAC,CAIF","file":"package-ULFSXQ7D.js","sourcesContent":["{\n \"type\": \"module\",\n \"name\": \"modelence\",\n \"version\": \"0.6.0-dev.1\",\n \"description\": \"The Node.js Framework for Real-Time MongoDB Apps\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/global.d.ts\",\n \"exports\": {\n \".\": \"./dist/index.js\",\n \"./client\": \"./dist/client.js\",\n \"./server\": \"./dist/server.js\",\n \"./telemetry\": \"./dist/telemetry.js\",\n \"./mongodb\": \"./dist/mongo.js\"\n },\n \"files\": [\n \"dist\",\n \"dist/bin\"\n ],\n \"bin\": {\n \"modelence\": \"./dist/bin/modelence.js\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"prepublishOnly\": \"npm run build\",\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n \"postversion\": \"git push && git push --tags\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/modelence/modelence.git\"\n },\n \"author\": \"Modelence\",\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"bugs\": {\n \"url\": \"https://github.com/modelence/modelence/issues\"\n },\n \"homepage\": \"https://modelence.com\",\n \"devDependencies\": {\n \"@types/archiver\": \"^6.0.3\",\n \"@types/bcrypt\": \"^5.0.2\",\n \"@types/cookie-parser\": \"^1.4.9\",\n \"@types/express\": \"^5.0.0\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/node\": \"^22.5.1\",\n \"@types/passport-google-oauth20\": \"^2.0.16\",\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.1\",\n \"@types/socket.io\": \"^3.0.1\",\n \"@typescript-eslint/eslint-plugin\": \"^8.17.0\",\n \"@typescript-eslint/parser\": \"^8.17.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\"\n },\n \"dependencies\": {\n \"@modelence/types\": \"^1.0.3\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"archiver\": \"^7.0.1\",\n \"bcrypt\": \"^5.1.1\",\n \"commander\": \"^12.0.0\",\n \"cookie-parser\": \"^1.4.7\",\n \"dotenv\": \"^16.4.5\",\n \"elastic-apm-node\": \"^4.8.0\",\n \"express\": \"^4.21.0\",\n \"fs-extra\": \"^11.2.0\",\n \"jiti\": \"^2.4.2\",\n \"mongodb\": \"^6.8.1\",\n \"open\": \"^10.1.0\",\n \"passport\": \"^0.7.0\",\n \"passport-google-oauth20\": \"^2.0.0\",\n \"socket.io\": \"^4.8.1\",\n \"socket.io-client\": \"^4.8.1\",\n \"tsup\": \"^8.3.6\",\n \"tsx\": \"^4.19.3\",\n \"typescript\": \"^5.7.2\",\n \"vite\": \"^6.0.3\",\n \"vite-plugin-eslint\": \"^1.8.1\",\n \"winston\": \"^3.15.0\",\n \"winston-elasticsearch\": \"^0.19.0\",\n \"zod\": \"^3.23.8\",\n \"zustand\": \"^5.0.2\"\n },\n \"peerDependencies\": {\n \"react\": \">=18.0.0\",\n \"react-dom\": \">=18.0.0\"\n }\n}\n"]}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Document, ObjectId } from 'mongodb';
|
|
2
|
-
|
|
3
|
-
type User = Document;
|
|
4
|
-
type UserInfo = {
|
|
5
|
-
id: string;
|
|
6
|
-
handle: string;
|
|
7
|
-
};
|
|
8
|
-
type Session = {
|
|
9
|
-
authToken: string;
|
|
10
|
-
expiresAt: Date;
|
|
11
|
-
userId: ObjectId | null;
|
|
12
|
-
};
|
|
13
|
-
type Permission = string;
|
|
14
|
-
type RoleDefinition = {
|
|
15
|
-
description?: string;
|
|
16
|
-
permissions: Permission[];
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
type CanAccessRoom = (props: {
|
|
20
|
-
user: User | null;
|
|
21
|
-
session: Session | null;
|
|
22
|
-
roles: string[];
|
|
23
|
-
}) => Promise<boolean>;
|
|
24
|
-
declare class ServerRoom<T = any> {
|
|
25
|
-
readonly roomCategory: string;
|
|
26
|
-
readonly canAccessRoom: CanAccessRoom | null;
|
|
27
|
-
constructor(roomCategory: string, canAccessRoom?: CanAccessRoom);
|
|
28
|
-
broadcast(roomId: string, data: T): void;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export { type Permission as P, type RoleDefinition as R, ServerRoom as S, type UserInfo as U, type Session as a };
|
package/dist/types-B7qvJJOF.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
type ConfigType = 'text' | 'string' | 'number' | 'boolean' | 'secret';
|
|
2
|
-
type ConfigKey = string;
|
|
3
|
-
type ConfigParams = {
|
|
4
|
-
type: ConfigType;
|
|
5
|
-
default: ValueType<ConfigType>;
|
|
6
|
-
isPublic: boolean;
|
|
7
|
-
};
|
|
8
|
-
type AppConfig = {
|
|
9
|
-
key: ConfigKey;
|
|
10
|
-
value: ValueType<ConfigType>;
|
|
11
|
-
type: ConfigType;
|
|
12
|
-
};
|
|
13
|
-
type ConfigSchema = {
|
|
14
|
-
[key: string]: ConfigParams;
|
|
15
|
-
};
|
|
16
|
-
type ValueType<T> = T extends 'number' ? number : T extends 'string' ? string : T extends 'text' ? string : T extends 'boolean' ? boolean : T extends 'secret' ? string : never;
|
|
17
|
-
|
|
18
|
-
export type { AppConfig as A, ConfigSchema as C, ConfigKey as a };
|