insite-users-server-ws 2.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Eugene Nesvetaev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # inSite users server side WebSocket API
2
+
3
+ ## Installation
4
+
5
+ ```sh
6
+ $ npm install insite-users-server-ws
7
+ ```
8
+
9
+ Or
10
+
11
+ ```sh
12
+ $ bun add insite-users-server-ws
13
+ ```
package/bun.lockb ADDED
Binary file
@@ -0,0 +1,48 @@
1
+ import type { WithUser } from "insite-subscriptions-server/ws";
2
+ import type { InSiteWebSocketServer, InSiteWebSocketServerClient } from "insite-ws/server";
3
+ import type { IncomingTransport } from "insite-ws-transfers/node";
4
+ import { InSiteCollections } from "insite-db";
5
+ import { type AbilitiesSchema, type Session, type SessionDoc, Users, type Options as UsersOptions } from "insite-users-server";
6
+ import { AbilitiesPublication, OrgsExtendedPublication, type OrgsExtendedPublicationOptions, OrgsPublication, type OrgsPublicationOptions, RolesPublication, type RolesPublicationOptions, SessionsPublication, UserPublication, type UserPublicationOptions, UsersExtendedPublication, type UsersExtendedPublicationOptions, UsersPublication, type UsersPublicationOptions } from "./publications";
7
+ export type Options<AS extends AbilitiesSchema> = {
8
+ wss: InSiteWebSocketServer;
9
+ collections: InSiteCollections;
10
+ users: UsersOptions<AS>;
11
+ publication?: UsersPublicationOptions;
12
+ extendedPublication?: UsersExtendedPublicationOptions;
13
+ userPublication?: UserPublicationOptions;
14
+ roles?: {
15
+ publication?: RolesPublicationOptions;
16
+ };
17
+ orgs?: {
18
+ publication?: OrgsPublicationOptions;
19
+ extendedPublication?: OrgsExtendedPublicationOptions;
20
+ };
21
+ getSessionProps?: (wssc: WithUser<InSiteWebSocketServerClient, AS>) => Partial<SessionDoc>;
22
+ incomingTransport?: IncomingTransport;
23
+ };
24
+ export declare class UsersServer<AS extends AbilitiesSchema> {
25
+ #private;
26
+ constructor(options: Options<AS>);
27
+ wss: Options<AS>["wss"];
28
+ users: Users<AS>;
29
+ getSessionProps: Options<AS>["getSessionProps"];
30
+ incomingTransport: Options<AS>["incomingTransport"];
31
+ abilitiesPublication: AbilitiesPublication<AS>;
32
+ rolesPublication: RolesPublication<AS>;
33
+ usersPublication: UsersPublication<AS>;
34
+ usersExtendedPublication: UsersExtendedPublication<AS>;
35
+ userPublication: UserPublication<AS>;
36
+ orgsPublication: OrgsPublication<AS>;
37
+ orgsExtendedPublication: OrgsExtendedPublication<AS>;
38
+ sessionsPublication: SessionsPublication<AS>;
39
+ init?: ((options: Options<AS>) => Promise<this>) | undefined;
40
+ whenReady(): Promise<this>;
41
+ getDefaultSessionProps({ userAgent, remoteAddress }: WithUser<InSiteWebSocketServerClient, AS>): {
42
+ userAgent: string;
43
+ remoteAddress: string;
44
+ };
45
+ setSession(wssc: WithUser<InSiteWebSocketServerClient, AS>, session: null | Session | string | undefined, shouldProlong?: boolean): void;
46
+ static init<IAS extends AbilitiesSchema>(options: Options<IAS>): Promise<UsersServer<IAS>>;
47
+ }
48
+ //# sourceMappingURL=UsersServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UsersServer.d.ts","sourceRoot":"","sources":["../src/UsersServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./UsersServer";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{_ids as Q,Err as p,includesAll as w,isEmpty as F,removeAll as N,union as V,without as M}from"@nesvet/n";import{Binary as X}from"insite-db";import{Users as Y}from"insite-users-server";import{CollectionMapPublication as y,Publication as z}from"insite-subscriptions-server/ws";import{_ids as K,includesAny as J,intersection as T,pick as E}from"@nesvet/n";var I=class extends z{constructor(e){super("abilities",{fetch(t){return t.user?.abilities.inSite?.sections?.includes("users")?{abilities:e.getSchemeFor(t.user)}:null}})}},W=class extends y{constructor(e,t={}){let{projection:a={title:1,description:1},sort:c={_o:1},transform:u}=t;Object.assign(a,{involves:1,abilities:1}),super("roles",e.collection,n=>n.user?.abilities.inSite?.sections?.includes("users")&&{query:{_id:{$in:n.user.slaveRoleIds}},projection:a,sort:c},n=>{let{involves:l,abilities:h,inheritedAbilities:d,displayTitle:S,_o:O}=e.get(n._id);Object.assign(n,{...n.involves?{ownInvolves:n.involves,involves:K(l),abilities:h,inheritedAbilities:d}:{},...a.title?{displayTitle:S}:{},_o:O}),u?.(n)})}},L=new WeakMap,x=class extends z{constructor(e,t={}){let{fieldsToUpdate:a=[],projection:c,transform:u}=t;for(let n of["email","name","name.first","name.middle","name.last","org","job","avatar"])(!c||c[n]!==0)&&a.push(n);super("user",{onSubscribe(n){let[{user:l}]=n.args;if(l){let{_id:h}=l,d=S=>{if("documentKey"in S&&S.documentKey._id===h)switch(S.operationType){case"update":if(!J(Object.keys(S.updateDescription.updatedFields),a))break;case"replace":case"delete":n.changed(S)}};e.collection.changeListeners.add(d),L.set(n,d)}},fetch({user:n,session:l},h){if(n){let d=E(n,["_id","email","name","initials","displayLabel","job","avatarUrl","abilities","slaveIds"]);if(Object.assign(d,{orgId:n.org._id,sessionId:h?l?._id:void 0,isOnline:!0}),c)for(let S in c)c[S]&&S in n?Object.assign(d,{[S]:n[S]}):delete d[S];return u?.(d),d}return null},onUnsubscribe(n){let l=L.get(n);l&&e.collection.changeListeners.delete(l)}})}},C=class extends y{constructor(e,t={}){let{projection:a={email:1,name:1,org:1,job:1,avatar:1},sort:c={"name.last":1},transform:u}=t;super("users",e.collection,n=>n.user?.abilities.login&&{query:{},projection:a,sort:c},n=>{let l=e.get(n._id);Object.assign(n,E(l,["initials","displayLabel","avatarUrl","isOnline"]),{orgId:n.org}),delete n.org,delete n.avatar,u?.(n)})}},R=class extends y{constructor(e,t={}){let{projection:a={_id:1},sort:c,triggers:u=[],transform:n}=t;u.includes("roles")||u.push("roles"),super("users.extended",e.collection,l=>l.user?.abilities.inSite?.sections?.includes("users")&&{query:{_id:{$in:l.user.slaveIds}},projection:a,sort:c,triggers:u},(l,[h])=>{let d=e.get(l._id);Object.assign(l,{roleIds:T(d.ownRoleIds,h.user.slaveRoleIds)}),n?.(l)})}},k=class extends y{constructor(e){super("users.people.sessions",e.collection,(t,a)=>t.user?.abilities.inSite?.sections?.includes("users")&&t.user.permissiveIds.includes(a)&&{query:{user:a},projection:{remoteAddress:1,isOnline:1,prolongedAt:1},sort:{prolongedAt:-1}})}},j=class extends y{constructor(e,t={}){let{projection:a={title:1},sort:c={title:1},transform:u}=t;super("orgs",e.collection,n=>n.user?.abilities.login&&{query:{},projection:a,sort:c},n=>{let l=e.get(n._id);Object.assign(n,E(l,["initials","displayLabel"])),u?.(n)})}},D=class extends y{constructor(e,t={}){let{projection:a={note:1},sort:c={_o:1},triggers:u=[],transform:n}=t;u.includes("owners")||u.push("owners"),super("orgs.extended",e.collection,l=>l.user?.abilities.inSite?.sections?.includes("users")&&{query:{_id:{$in:l.user.slaveIds}},projection:a,sort:c,triggers:u},(l,[h])=>{let d=e.get(l._id),{ownerIds:S,slaveOrgs:O,_o:q}=d;Object.assign(l,{owners:T(S,h.user.slaveIds),slaveOrgs:K(T(O,h.user.slaveOrgs)),_o:q}),n?.(l)})}};var _={email:/^[^\s@]{1,63}@[^\s@]{1,63}\.[^\s@]{1,63}$/,role:/^[\d_a-z-]{1,64}$/};var Z=["image/webp"],ee=1024*512,B=class m{constructor(e){this.#i=this.init(e)}#e=new WeakMap;#s=new WeakMap;wss;users;getSessionProps;incomingTransport;abilitiesPublication;rolesPublication;usersPublication;usersExtendedPublication;userPublication;orgsPublication;orgsExtendedPublication;sessionsPublication;init=async e=>{let{wss:t,collections:a,users:c,publication:u,extendedPublication:n,userPublication:l,roles:h={},orgs:d={},getSessionProps:S,incomingTransport:O}=e,{publication:q}=h,{publication:G,extendedPublication:H}=d;this.wss=t,this.users=await Y.init(a,c),this.getSessionProps=S,this.incomingTransport=O;for(let s of this.users.values())this.#t(s);if(this.abilitiesPublication=new I(this.users.abilitiesMap),this.rolesPublication=new W(this.users.roles,q),this.usersPublication=new C(this.users,u),this.usersExtendedPublication=new R(this.users,n),this.userPublication=new x(this.users,l),this.orgsPublication=new j(this.users.orgs,G),this.orgsExtendedPublication=new D(this.users.orgs,H),this.sessionsPublication=new k(this.users.sessions),this.users.on("roles-update",this.#o),this.users.on("roles-role-update",this.#l),this.users.on("user-create",this.#t),this.users.on("user-is-online",this.#a),this.users.on("session-delete",this.#c),this.users.on("orgs-update",this.#u),this.users.on("orgs-org-update",this.#S),this.users.on("user-permissions-change",this.#d),this.wss.onRequest("login",this.#p),this.wss.onRequest("logout",this.#h),this.wss.on("client-closed",this.#b),this.wss.onRequest("users.people.check-email",(s,i)=>{if(s.user?.abilities.inSite?.sections?.includes("users")){if(!_.email.test(i))throw new p("Not email","notemail");if(this.users.byEmail.has(i))throw new p("Email already exists","exists")}}),this.wss.onRequest("users.people.add",async(s,{roles:i,org:r,...o})=>{if(s.user?.abilities.inSite?.sections?.includes("users")){if(!i.length)throw new p("Roles shouldn't be empty","emptyroles");if(!w(s.user.slaveRoleIds,i))throw new p("Can't assign role the user is not involved in","forbiddenrole");if(r&&!s.user.slaveIds.includes(r))throw new p("Can't assign org the user is not master of","forbiddenorg");await this.users.new({roles:i,org:r,...o})}}),this.wss.onRequest("users.people.change-password",async(s,i,r)=>{if(s.user?.abilities.inSite?.sections?.includes("users")&&s.user.permissiveIds.includes(i)){if(typeof r!="string")throw new p("Type of password is incorrect","wrongpasswordtype");if(!r)throw new p("Password can't be empty","emptypassword");await this.users.changePassword(i,r)}}),this.wss.onRequest("users.people.update",async(s,i,r)=>{if(s.user?.abilities.inSite?.sections?.includes("users")&&s.user.permissiveIds.includes(i)){if(r.roles){if(!r.roles.length)throw new p("Roles can't be empty","emptyroles");if(!w(s.user.slaveRoleIds,r.roles))throw new p("Can't assign role the user is not involved in","forbiddenrole");let o=this.users.get(i);o&&(r.roles=o.isRoot?["root"]:this.users.roles.cleanUpIds(M(o.ownRoleIds,s.user.slaveRoleIds).concat(r.roles)))}if(r.org&&!s.user.slaveIds.includes(r.org))throw new p("Can't assign org the user is not master of","forbiddenorg");F(r)||await this.users.collection.updateOne({_id:i},{$set:r})}}),this.wss.onRequest("users.people.delete",async(s,i)=>{s.user?.abilities.inSite?.sections?.includes("users")&&s.user.slaveIds.includes(i)&&await this.users.collection.deleteOne({_id:i})}),this.wss.onRequest("users.people.destroy-session",async(s,i)=>{s.user?.abilities.inSite?.sections?.includes("users")&&s.user.permissiveIds.includes(this.users.bySessionId.get(i)?._id)&&await this.users.sessions.collection.deleteOne({_id:i})}),this.incomingTransport){let s=i=>({begin:async(r,o)=>(!i||await i(r,o))&&Z.includes(o.metadata.type)&&o.size<=ee,end:async(r,{data:o,metadata:{type:b,_id:A}})=>{let g=X.createFromBase64(o.slice(o.indexOf(","))),v=Date.now().toString(36);await Promise.all([this.users.avatars.collection.replaceOne({_id:A},{type:b,size:g.length(),ts:v,data:g},{upsert:!0}),this.users.collection.updateOne({_id:A},{$set:{avatar:v}})])}});this.incomingTransport.on("users.people.avatar",s((i,{metadata:{_id:r}})=>i.user?.abilities.inSite?.sections?.includes("users")&&i.user.permissiveIds.includes(r))),this.incomingTransport.on("user.avatar",s((i,r)=>i.user&&i.user._id===r.metadata._id))}let $=async s=>{await Promise.all([this.users.avatars.collection.deleteOne({_id:s}),this.users.collection.updateOne({_id:s},{$set:{avatar:null}})])};return this.wss.onRequest("users.people.delete-avatar",async(s,i)=>s.user?.abilities.inSite?.sections?.includes("users")&&s.user.permissiveIds.includes(i)&&await $(i)),this.wss.onRequest("user.delete-avatar",async(s,i)=>s.user&&s.user._id===i&&await $(i)),this.wss.onRequest("users.orgs.add",async(s,i)=>{if(s.user?.abilities.inSite?.sections?.includes("users")){if(!i.title)throw new p("Title can't be empty","emptytitle");await this.users.orgs.new(i,s.user._id)}}),this.wss.onRequest("users.orgs.update",async(s,i,r)=>{if(s.user?.abilities.inSite?.sections?.includes("users")&&s.user.slaveIds.includes(i)){if(r.title!==void 0&&!r.title)throw new p("Title can't be empty","emptytitle");if(r.owners){if(!w(s.user.slaveIds,r.owners))throw new p("Can't assign owners the user is not master of","forbiddenowners");let o=this.users.orgs.get(i);o&&(r.owners=this.users.sortIds(V(M(o.ownerIds,s.user.slaveIds),M(r.owners,[o._id,...Q(o.slaveOrgs)]))))}F(r)||await this.users.orgs.collection.updateOne({_id:i},{$set:r})}}),this.wss.onRequest("users.orgs.delete",async(s,i)=>{s.user?.abilities.inSite?.sections?.includes("users")&&s.user.slaveIds.includes(i)&&await this.users.orgs.collectionDelete(i)}),this.wss.onRequest("users.roles.check-id",(s,i)=>{if(s.user?.abilities.inSite?.sections?.includes("users")){if(!_.role.test(i))throw new p("Role ID is incorrect","notroleid");if(this.users.roles.has(i))throw new p("Role ID already exists","exists")}}),this.wss.onRequest("users.roles.add",async(s,i)=>{s.user?.abilities.inSite?.sections?.includes("users")&&await this.users.roles.new(i)}),this.wss.onRequest("users.roles.update",async(s,i,{abilities:r,...o})=>{if(s.user?.abilities.inSite?.sections?.includes("users")&&s.user.slaveRoleIds.includes(i)){if(o.involves)if(w(s.user.slaveRoleIds,o.involves)){N(o.involves,[i]);let b=this.users.roles.get(i);if(b)for(let A of o.involves)this.users.roles.get(A)?.involves.has(b)&&N(o.involves,[A]);o.involves=this.users.roles.cleanUpIds(o.involves)}else throw new p("Can't assign role the user is not involved in","forbiddenrole");await this.users.roles.collection.updateOne({_id:i},{$set:o})}}),this.wss.onRequest("users.roles.set-ability",async(s,i,r,o,b)=>{if(s.user?.abilities.inSite?.sections?.includes("users")&&s.user.slaveRoleIds.includes(i)&&s.user.abilities[r]){let A=this.users.roles.get(i);if(A){let g=structuredClone(A.ownAbilities),v;if(o){g[r]||(g[r]={});let P=this.users.abilitiesMap.get(r)?.params?.find(f=>f._id===o);if(P){let f=s.user.abilities[r],U=g[r];P.type==="number"?f[o]>=b&&(U[o]=b,v=!0):P.type==="items"&&f[o]&&w(f[o],b)&&(U[o]=b,v=!0)}}else b?g[r]=this.users.abilitiesMap.getMinimumOf(r):function P(f){if(f&&(delete g[f._id],f.subAbilities))for(let U of f.subAbilities)g[U._id]&&P(U)}(this.users.abilitiesMap.get(r)),v=!0;v&&await this.users.roles.collection.updateOne({_id:i},{$set:{abilities:g}})}}}),this.wss.on("client-message:users.roles.delete",async(s,i)=>{s.user?.abilities.inSite?.sections?.includes("users")&&s.user.slaveRoleIds.includes(i)&&await this.users.roles.collectionDelete(i)}),this};#i;whenReady(){return this.#i}getDefaultSessionProps({userAgent:e,remoteAddress:t}){return{userAgent:e,remoteAddress:t}}setSession(e,t,a){t===null?t=void 0:typeof t=="string"&&(t=this.users.sessions.get(t)),e.session!==t&&(e.session&&this.#s.delete(e.session),t?(e.session=t,e.user=t.user,e.lastUserId=t.user._id,this.#e.get(t.user)?.add(e),this.#s.set(t,e),a&&t.prolong({...this.getDefaultSessionProps(e),...this.getSessionProps?.(e),isOnline:!0})):(delete e.session,this.#e.get(e.user)?.delete(e)),this.wss.emit("client-session",e,a))}#n=async(e,t,a)=>{let c=await this.users.login(t,a,{...this.getDefaultSessionProps(e),...this.getSessionProps?.(e),isOnline:!0});c&&this.setSession(e,c)};#r=e=>{e.session&&(this.users.logout(e.session),this.setSession(e,null))};#o=()=>this.rolesPublication.flushInitial();#l=(e,t)=>t&&this.rolesPublication.skip(t);#t=e=>this.#e.set(e,new Set);#a=({_id:e,isOnline:t})=>{let a={_id:e,isOnline:t};for(let c of this.usersPublication.subscriptions){let[u]=c.args;u.user&&u.user._id!==e&&c.handler([["u",a,!0]])}};#c=e=>{let t=this.#s.get(e);t&&this.setSession(t,null)};#u=()=>{this.orgsPublication.flushInitial(),this.orgsExtendedPublication.flushInitial()};#S=(e,t)=>{t&&(this.orgsPublication.skip(t),this.orgsExtendedPublication.skip(t))};#d=e=>{let t=this.#e.get(e);t&&this.wss.emit("should-renew-subscriptions",[...t])};#p=(e,t,a)=>this.#n(e,t,a);#h=e=>this.#r(e);#b=e=>{e.session?.offline(),this.setSession(e,null)};static init(e){return new m(e).whenReady()}};export{B as UsersServer};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/UsersServer.ts", "../src/publications.ts", "../src/regexps.ts"],
4
+ "sourcesContent": ["import type { WithUser } from \"insite-subscriptions-server/ws\";\nimport type { InSiteWebSocketServer, InSiteWebSocketServerClient } from \"insite-ws/server\";\nimport type { IncomingTransfer, IncomingTransport } from \"insite-ws-transfers/node\";\nimport {\n\t_ids,\n\tErr,\n\tincludesAll,\n\tisEmpty,\n\tremoveAll,\n\tStringKey,\n\tunion,\n\twithout\n} from \"@nesvet/n\";\nimport { Binary, type ChangeStreamDocument, InSiteCollections } from \"insite-db\";\nimport {\n\ttype Abilities,\n\ttype AbilitiesSchema,\n\ttype AbilityParamItems,\n\ttype AbilityParamNumber,\n\ttype AbilityWithParams,\n\ttype GenericAbilities,\n\ttype Org,\n\ttype OrgDoc,\n\ttype Role,\n\ttype RoleDoc,\n\ttype Session,\n\ttype SessionDoc,\n\ttype User,\n\ttype UserDoc,\n\tUsers,\n\ttype Options as UsersOptions\n} from \"insite-users-server\";\nimport {\n\tAbilitiesPublication,\n\tOrgsExtendedPublication,\n\ttype OrgsExtendedPublicationOptions,\n\tOrgsPublication,\n\ttype OrgsPublicationOptions,\n\tRolesPublication,\n\ttype RolesPublicationOptions,\n\tSessionsPublication,\n\tUserPublication,\n\ttype UserPublicationOptions,\n\tUsersExtendedPublication,\n\ttype UsersExtendedPublicationOptions,\n\tUsersPublication,\n\ttype UsersPublicationOptions\n} from \"./publications\";\nimport { regexps } from \"./regexps\";\n\nconst avatarTypesAccepted = [ \"image/webp\" ];\nconst maxAvatarSize = 1024 * 512;\n\nexport type Options<AS extends AbilitiesSchema> = {\n\twss: InSiteWebSocketServer;\n\tcollections: InSiteCollections;\n\tusers: UsersOptions<AS>;\n\tpublication?: UsersPublicationOptions;\n\textendedPublication?: UsersExtendedPublicationOptions;\n\tuserPublication?: UserPublicationOptions;\n\troles?: {\n\t\tpublication?: RolesPublicationOptions;\n\t};\n\torgs?: {\n\t\tpublication?: OrgsPublicationOptions;\n\t\textendedPublication?: OrgsExtendedPublicationOptions;\n\t};\n\tgetSessionProps?: (wssc: WithUser<InSiteWebSocketServerClient, AS>) => Partial<SessionDoc>;\n\tincomingTransport?: IncomingTransport;\n};\n\n\nexport class UsersServer<AS extends AbilitiesSchema> {\n\tconstructor(options: Options<AS>) {\n\t\tthis.#initPromise = this.init!(options);\n\t\t\n\t}\n\t\n\t#userWsMap = new WeakMap<User<AS>, Set<WithUser<InSiteWebSocketServerClient, AS>>>();\n\t#sessionsWsMap = new WeakMap<Session<AS>, WithUser<InSiteWebSocketServerClient, AS>>();\n\t\n\twss!: Options<AS>[\"wss\"];\n\tusers!: Users<AS>;\n\tgetSessionProps!: Options<AS>[\"getSessionProps\"];\n\tincomingTransport!: Options<AS>[\"incomingTransport\"];\n\t\n\tabilitiesPublication!: AbilitiesPublication<AS>;\n\trolesPublication!: RolesPublication<AS>;\n\tusersPublication!: UsersPublication<AS>;\n\tusersExtendedPublication!: UsersExtendedPublication<AS>;\n\tuserPublication!: UserPublication<AS>;\n\torgsPublication!: OrgsPublication<AS>;\n\torgsExtendedPublication!: OrgsExtendedPublication<AS>;\n\tsessionsPublication!: SessionsPublication<AS>;\n\t\n\tinit? = async (options: Options<AS>) => {\n\t\t\n\t\tconst {\n\t\t\twss,\n\t\t\tcollections,\n\t\t\tusers: usersOptions,\n\t\t\tpublication: publicationOptions,\n\t\t\textendedPublication: extendedPublicationOptions,\n\t\t\tuserPublication: userPublicationOptions,\n\t\t\troles: rolesOptions = {},\n\t\t\torgs: orgsOptions = {},\n\t\t\tgetSessionProps,\n\t\t\tincomingTransport\n\t\t} = options;\n\t\t\n\t\tconst {\n\t\t\tpublication: rolesPublicationOptions\n\t\t} = rolesOptions;\n\t\t\n\t\tconst {\n\t\t\tpublication: orgsPublicationOptions,\n\t\t\textendedPublication: orgsExtendedPublicationOptions\n\t\t} = orgsOptions;\n\t\t\n\t\tthis.wss = wss;\n\t\tthis.users = await Users.init(collections, usersOptions);\n\t\tthis.getSessionProps = getSessionProps;\n\t\tthis.incomingTransport = incomingTransport;\n\t\t\n\t\tfor (const user of this.users.values())\n\t\t\tthis.#handleUserCreate(user);\n\t\t\n\t\tthis.abilitiesPublication = new AbilitiesPublication<AS>(this.users.abilitiesMap);\n\t\tthis.rolesPublication = new RolesPublication<AS>(this.users.roles, rolesPublicationOptions);\n\t\tthis.usersPublication = new UsersPublication<AS>(this.users, publicationOptions);\n\t\tthis.usersExtendedPublication = new UsersExtendedPublication<AS>(this.users, extendedPublicationOptions);\n\t\tthis.userPublication = new UserPublication<AS>(this.users, userPublicationOptions);\n\t\tthis.orgsPublication = new OrgsPublication<AS>(this.users.orgs, orgsPublicationOptions);\n\t\tthis.orgsExtendedPublication = new OrgsExtendedPublication<AS>(this.users.orgs, orgsExtendedPublicationOptions);\n\t\tthis.sessionsPublication = new SessionsPublication<AS>(this.users.sessions);\n\t\t\n\t\tthis.users.on(\"roles-update\", this.#handleRolesUpdate);\n\t\tthis.users.on(\"roles-role-update\", this.#handleRolesRoleUpdate);\n\t\tthis.users.on(\"user-create\", this.#handleUserCreate);\n\t\tthis.users.on(\"user-is-online\", this.#handleUserIsOnline);\n\t\tthis.users.on(\"session-delete\", this.#handleSessionDelete);\n\t\tthis.users.on(\"orgs-update\", this.#handleOrgsUpdate);\n\t\tthis.users.on(\"orgs-org-update\", this.#handleOrgsOrgUpdate);\n\t\tthis.users.on(\"user-permissions-change\", this.#handleUserPermissionsChange);\n\t\t\n\t\tthis.wss.onRequest(\"login\", this.#handleClientRequestLogin);\n\t\tthis.wss.onRequest(\"logout\", this.#handleClientRequestLogout);\n\t\tthis.wss.on(\"client-closed\", this.#handleClientClosed);\n\t\t\n\t\t\n\t\t/*\n\t\t * Handlers\n\t\t */\n\t\t\n\t\t/* Users */\n\t\t\n\t\tthis.wss.onRequest(\"users.people.check-email\", (wssc: WithUser<InSiteWebSocketServerClient, AS>, email: string) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\")) {\n\t\t\t\tif (!regexps.email.test(email))\n\t\t\t\t\tthrow new Err(\"Not email\", \"notemail\");\n\t\t\t\t\n\t\t\t\tif (this.users.byEmail.has(email))\n\t\t\t\t\tthrow new Err(\"Email already exists\", \"exists\");\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.people.add\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, { roles, org, ...rest }: Omit<UserDoc, \"_id\" | \"createdAt\">) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\")) {\n\t\t\t\tif (!roles.length)\n\t\t\t\t\tthrow new Err(\"Roles shouldn't be empty\", \"emptyroles\");\n\t\t\t\t\n\t\t\t\tif (!includesAll(wssc.user.slaveRoleIds, roles))\n\t\t\t\t\tthrow new Err(\"Can't assign role the user is not involved in\", \"forbiddenrole\");\n\t\t\t\t\n\t\t\t\tif (org && !wssc.user.slaveIds.includes(org))\n\t\t\t\t\tthrow new Err(\"Can't assign org the user is not master of\", \"forbiddenorg\");\n\t\t\t\t\n\t\t\t\tawait this.users.new({ roles, org, ...rest });\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.people.change-password\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string, newPassword: string) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.permissiveIds.includes(_id)) {\n\t\t\t\tif (typeof newPassword != \"string\")\n\t\t\t\t\tthrow new Err(\"Type of password is incorrect\", \"wrongpasswordtype\");\n\t\t\t\t\n\t\t\t\tif (!newPassword)\n\t\t\t\t\tthrow new Err(\"Password can't be empty\", \"emptypassword\");\n\t\t\t\t\n\t\t\t\tawait this.users.changePassword(_id, newPassword);\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.people.update\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string, updates: Omit<UserDoc, \"_id\" | \"createdAt\">) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.permissiveIds.includes(_id)) {\n\t\t\t\tif (updates.roles) {\n\t\t\t\t\tif (!updates.roles.length)\n\t\t\t\t\t\tthrow new Err(\"Roles can't be empty\", \"emptyroles\");\n\t\t\t\t\t\n\t\t\t\t\tif (!includesAll(wssc.user.slaveRoleIds, updates.roles))\n\t\t\t\t\t\tthrow new Err(\"Can't assign role the user is not involved in\", \"forbiddenrole\");\n\t\t\t\t\t\n\t\t\t\t\tconst user = this.users.get(_id);\n\t\t\t\t\t\n\t\t\t\t\tif (user)\n\t\t\t\t\t\tupdates.roles =\n\t\t\t\t\t\t\tuser.isRoot ?\n\t\t\t\t\t\t\t\t[ \"root\" ] :\n\t\t\t\t\t\t\t\tthis.users.roles.cleanUpIds(\n\t\t\t\t\t\t\t\t\twithout(user.ownRoleIds, wssc.user.slaveRoleIds).concat(updates.roles)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (updates.org && !wssc.user.slaveIds.includes(updates.org))\n\t\t\t\t\tthrow new Err(\"Can't assign org the user is not master of\", \"forbiddenorg\");\n\t\t\t\t\n\t\t\t\tif (!isEmpty(updates))\n\t\t\t\t\tawait this.users.collection.updateOne({ _id }, { $set: updates });\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.people.delete\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.slaveIds.includes(_id))\n\t\t\t\tawait this.users.collection.deleteOne({ _id });\n\t\t\t\n\t\t});\n\t\t\n\t\t\n\t\t/* Sessions */\n\t\t\n\t\tthis.wss.onRequest(\"users.people.destroy-session\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, sessionId: string) => {\n\t\t\tif (\n\t\t\t\twssc.user?.abilities.inSite?.sections?.includes(\"users\") &&\n\t\t\t\twssc.user.permissiveIds.includes(this.users.bySessionId.get(sessionId)?._id)\n\t\t\t)\n\t\t\t\tawait this.users.sessions.collection.deleteOne({ _id: sessionId });\n\t\t\t\n\t\t});\n\t\t\n\t\t\n\t\t/* Avatars */\n\t\t\n\t\tif (this.incomingTransport) {\n\t\t\tconst getAvatarTransferProps = (check?: (wssc: WithUser<InSiteWebSocketServerClient, AS>, transfer: IncomingTransfer) => boolean | Promise<boolean | undefined> | undefined) => ({\n\t\t\t\t\n\t\t\t\tbegin: async (wssc: InSiteWebSocketServerClient, transfer: IncomingTransfer) => (\n\t\t\t\t\t(!check || await check(wssc, transfer)) &&\n\t\t\t\t\tavatarTypesAccepted.includes(transfer.metadata.type as string) &&\n\t\t\t\t\ttransfer.size <= maxAvatarSize\n\t\t\t\t),\n\t\t\t\t\n\t\t\t\tend: async (wssc: InSiteWebSocketServerClient, { data, metadata: { type, _id } }: IncomingTransfer) => {\n\t\t\t\t\tconst binaryData = Binary.createFromBase64((data as string).slice((data as string).indexOf(\",\")));\n\t\t\t\t\t\n\t\t\t\t\tconst ts = Date.now().toString(36);\n\t\t\t\t\t\n\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\tthis.users.avatars.collection.replaceOne({ _id: _id as string }, {\n\t\t\t\t\t\t\ttype: type as string,\n\t\t\t\t\t\t\tsize: binaryData.length(),\n\t\t\t\t\t\t\tts,\n\t\t\t\t\t\t\tdata: binaryData\n\t\t\t\t\t\t}, { upsert: true }),\n\t\t\t\t\t\tthis.users.collection.updateOne({ _id: _id as string }, { $set: { avatar: ts } })\n\t\t\t\t\t]);\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\t\t\t\n\t\t\tthis.incomingTransport.on(\"users.people.avatar\", getAvatarTransferProps(\n\t\t\t\t(wssc: WithUser<InSiteWebSocketServerClient, AS>, { metadata: { _id } }: IncomingTransfer) =>\n\t\t\t\t\twssc.user?.abilities.inSite?.sections?.includes(\"users\") &&\n\t\t\t\t\twssc.user.permissiveIds.includes(_id as string)\n\t\t\t));\n\t\t\t\n\t\t\tthis.incomingTransport.on(\"user.avatar\", getAvatarTransferProps(\n\t\t\t\t(wssc: WithUser<InSiteWebSocketServerClient, AS>, transfer: IncomingTransfer) =>\n\t\t\t\t\twssc.user &&\n\t\t\t\t\twssc.user._id === transfer.metadata._id\n\t\t\t));\n\t\t}\n\t\t\n\t\tconst deleteAvatar = async (_id: string) => {\n\t\t\t\n\t\t\tawait Promise.all([\n\t\t\t\tthis.users.avatars.collection.deleteOne({ _id }),\n\t\t\t\tthis.users.collection.updateOne({ _id }, { $set: { avatar: null } })\n\t\t\t]);\n\t\t\t\n\t\t};\n\t\t\n\t\tthis.wss.onRequest(\"users.people.delete-avatar\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string) =>\n\t\t\twssc.user?.abilities.inSite?.sections?.includes(\"users\") &&\n\t\t\twssc.user.permissiveIds.includes(_id) &&\n\t\t\tawait deleteAvatar(_id)\n\t\t);\n\t\t\n\t\tthis.wss.onRequest(\"user.delete-avatar\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string) =>\n\t\t\twssc.user &&\n\t\t\twssc.user._id === _id &&\n\t\t\tawait deleteAvatar(_id)\n\t\t);\n\t\t\n\t\t\n\t\t/* Orgs */\n\t\t\n\t\tthis.wss.onRequest(\"users.orgs.add\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, org: Omit<OrgDoc, \"_id\" | \"createdAt\" | \"owners\">) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\")) {\n\t\t\t\tif (!org.title)\n\t\t\t\t\tthrow new Err(\"Title can't be empty\", \"emptytitle\");\n\t\t\t\t\n\t\t\t\tawait this.users.orgs.new(org, wssc.user._id);\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.orgs.update\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id, updates: Omit<OrgDoc, \"_id\" | \"createdAt\">) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.slaveIds.includes(_id)) {\n\t\t\t\tif (updates.title !== undefined && !updates.title)\n\t\t\t\t\tthrow new Err(\"Title can't be empty\", \"emptytitle\");\n\t\t\t\t\n\t\t\t\tif (updates.owners) {\n\t\t\t\t\tif (!includesAll(wssc.user.slaveIds, updates.owners))\n\t\t\t\t\t\tthrow new Err(\"Can't assign owners the user is not master of\", \"forbiddenowners\");\n\t\t\t\t\t\n\t\t\t\t\tconst org = this.users.orgs.get(_id);\n\t\t\t\t\t\n\t\t\t\t\tif (org)\n\t\t\t\t\t\tupdates.owners =\n\t\t\t\t\t\t\tthis.users.sortIds(\n\t\t\t\t\t\t\t\tunion(\n\t\t\t\t\t\t\t\t\twithout(org.ownerIds, wssc.user.slaveIds),\n\t\t\t\t\t\t\t\t\twithout(updates.owners, [ org._id, ..._ids(org.slaveOrgs) ])\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (!isEmpty(updates))\n\t\t\t\t\tawait this.users.orgs.collection.updateOne({ _id }, { $set: updates });\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.orgs.delete\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.slaveIds.includes(_id))\n\t\t\t\tawait this.users.orgs.collectionDelete(_id);\n\t\t\t\n\t\t});\n\t\t\n\t\t\n\t\t/* Roles */\n\t\t\n\t\tthis.wss.onRequest(\"users.roles.check-id\", (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\")) {\n\t\t\t\tif (!regexps.role.test(_id))\n\t\t\t\t\tthrow new Err(\"Role ID is incorrect\", \"notroleid\");\n\t\t\t\t\n\t\t\t\tif (this.users.roles.has(_id))\n\t\t\t\t\tthrow new Err(\"Role ID already exists\", \"exists\");\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.roles.add\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, role: Omit<RoleDoc, \"abilities\" | \"createdAt\">) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\"))\n\t\t\t\tawait this.users.roles.new(role);\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.roles.update\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string, { abilities, ...updates }: Omit<RoleDoc, \"createdAt\">) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.slaveRoleIds.includes(_id)) {\n\t\t\t\tif (updates.involves)\n\t\t\t\t\tif (includesAll(wssc.user.slaveRoleIds, updates.involves)) {\n\t\t\t\t\t\tremoveAll(updates.involves, [ _id ]);\n\t\t\t\t\t\t\n\t\t\t\t\t\tconst role = this.users.roles.get(_id);\n\t\t\t\t\t\tif (role)\n\t\t\t\t\t\t\tfor (const involvedRoleId of updates.involves)\n\t\t\t\t\t\t\t\tif (this.users.roles.get(involvedRoleId)?.involves.has(role))\n\t\t\t\t\t\t\t\t\tremoveAll(updates.involves, [ involvedRoleId ]);\n\t\t\t\t\t\t\n\t\t\t\t\t\tupdates.involves = this.users.roles.cleanUpIds(updates.involves);\n\t\t\t\t\t} else\n\t\t\t\t\t\tthrow new Err(\"Can't assign role the user is not involved in\", \"forbiddenrole\");\n\t\t\t\t\n\t\t\t\tawait this.users.roles.collection.updateOne({ _id }, { $set: updates });\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.onRequest(\"users.roles.set-ability\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string, abilityId: StringKey<Abilities<AS>>, paramId: string, value: unknown) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.slaveRoleIds.includes(_id) && wssc.user.abilities[abilityId]) {\n\t\t\t\tconst role = this.users.roles.get(_id);\n\t\t\t\tif (role) {\n\t\t\t\t\tconst abilities = structuredClone(role.ownAbilities) as GenericAbilities;\n\t\t\t\t\tlet shouldUpdate;\n\t\t\t\t\t\n\t\t\t\t\tif (paramId) {\n\t\t\t\t\t\tif (!abilities[abilityId])\n\t\t\t\t\t\t\tabilities[abilityId] = {};\n\t\t\t\t\t\tconst param = this.users.abilitiesMap.get(abilityId)?.params?.find(anotherParam => anotherParam._id === paramId);\n\t\t\t\t\t\tif (param) {\n\t\t\t\t\t\t\tconst userAbilityWithParams = wssc.user.abilities[abilityId] as AbilityWithParams;\n\t\t\t\t\t\t\tconst abilityWithParams = abilities[abilityId] as AbilityWithParams;\n\t\t\t\t\t\t\tif (param.type === \"number\") {\n\t\t\t\t\t\t\t\tif ((userAbilityWithParams[paramId] as AbilityParamNumber) >= (value as number)) {\n\t\t\t\t\t\t\t\t\tabilityWithParams[paramId] = value as number;\n\t\t\t\t\t\t\t\t\tshouldUpdate = true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (param.type === \"items\" && userAbilityWithParams[paramId] && includesAll(userAbilityWithParams[paramId] as AbilityParamItems, value as string[])) {\n\t\t\t\t\t\t\t\tabilityWithParams[paramId] = value as string[];\n\t\t\t\t\t\t\t\tshouldUpdate = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (value)\n\t\t\t\t\t\t\tabilities[abilityId] = this.users.abilitiesMap.getMinimumOf(abilityId);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t(function resolve(schema) {\n\t\t\t\t\t\t\t\tif (schema) {\n\t\t\t\t\t\t\t\t\tdelete abilities[schema._id];\n\t\t\t\t\t\t\t\t\tif (schema.subAbilities)\n\t\t\t\t\t\t\t\t\t\tfor (const subSchema of schema.subAbilities)\n\t\t\t\t\t\t\t\t\t\t\tif (abilities[subSchema._id])\n\t\t\t\t\t\t\t\t\t\t\t\tresolve(subSchema);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t})(this.users.abilitiesMap.get(abilityId));\n\t\t\t\t\t\t\n\t\t\t\t\t\tshouldUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (shouldUpdate)\n\t\t\t\t\t\tawait this.users.roles.collection.updateOne({ _id }, { $set: { abilities } });\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t\tthis.wss.on(\"client-message:users.roles.delete\", async (wssc: WithUser<InSiteWebSocketServerClient, AS>, _id: string) => {\n\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.slaveRoleIds.includes(_id))\n\t\t\t\tawait this.users.roles.collectionDelete(_id);\n\t\t\t\n\t\t});\n\t\t\n\t\treturn this;\n\t};\n\t\n\t#initPromise;\n\t\n\twhenReady() {\n\t\treturn this.#initPromise;\n\t}\n\t\n\tgetDefaultSessionProps({ userAgent, remoteAddress }: WithUser<InSiteWebSocketServerClient, AS>) {\n\t\treturn {\n\t\t\tuserAgent,\n\t\t\tremoteAddress\n\t\t};\n\t}\n\t\n\tsetSession(wssc: WithUser<InSiteWebSocketServerClient, AS>, session: null | Session | string | undefined, shouldProlong?: boolean) {\n\t\tif (session === null)\n\t\t\tsession = undefined;\n\t\telse if (typeof session == \"string\")\n\t\t\tsession = this.users.sessions.get(session);\n\t\t\n\t\tif (wssc.session !== session) {\n\t\t\tif (wssc.session)\n\t\t\t\tthis.#sessionsWsMap.delete(wssc.session);\n\t\t\t\n\t\t\tif (session) {\n\t\t\t\twssc.session = session;\n\t\t\t\twssc.user = session.user;\n\t\t\t\twssc.lastUserId = session.user._id;\n\t\t\t\tthis.#userWsMap.get(session.user)?.add(wssc);\n\t\t\t\tthis.#sessionsWsMap.set(session, wssc);\n\t\t\t\t\n\t\t\t\tif (shouldProlong)\n\t\t\t\t\tsession.prolong({\n\t\t\t\t\t\t...this.getDefaultSessionProps(wssc),\n\t\t\t\t\t\t...this.getSessionProps?.(wssc),\n\t\t\t\t\t\tisOnline: true\n\t\t\t\t\t});\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\tdelete wssc.session;\n\t\t\t\tthis.#userWsMap.get(wssc.user!)?.delete(wssc);\n\t\t\t}\n\t\t\t\n\t\t\tthis.wss.emit(\"client-session\", wssc, shouldProlong);\n\t\t}\n\t\t\n\t}\n\t\n\t#login = async (wssc: WithUser<InSiteWebSocketServerClient, AS>, email: string, password: string) => {\n\t\tconst session = await this.users.login(email, password, {\n\t\t\t...this.getDefaultSessionProps(wssc),\n\t\t\t...this.getSessionProps?.(wssc),\n\t\t\tisOnline: true\n\t\t});\n\t\t\n\t\tif (session)\n\t\t\tthis.setSession(wssc, session);\n\t\t\n\t};\n\t\n\t#logout = (wssc: WithUser<InSiteWebSocketServerClient, AS>) => {\n\t\tif (wssc.session) {\n\t\t\tthis.users.logout(wssc.session);\n\t\t\tthis.setSession(wssc, null);\n\t\t}\n\t\t\n\t};\n\t\n\t#handleRolesUpdate = () =>\n\t\tthis.rolesPublication.flushInitial();\n\t\n\t#handleRolesRoleUpdate = (role: Role, next: ChangeStreamDocument<RoleDoc>) =>\n\t\tnext && this.rolesPublication.skip(next);\n\t\n\t#handleUserCreate = (user: User) =>\n\t\tthis.#userWsMap.set(user, new Set<WithUser<InSiteWebSocketServerClient, AS>>());\n\t\n\t#handleUserIsOnline = ({ _id, isOnline }: User) => {\n\t\tconst updates = { _id, isOnline };\n\t\t\n\t\tfor (const usersSubscription of this.usersPublication.subscriptions) {\n\t\t\tconst [ wssc ] = usersSubscription.args;\n\t\t\tif (wssc.user && wssc.user._id !== _id)\n\t\t\t\tusersSubscription.handler([ [ \"u\"/* update */, updates, true ] ]);\n\t\t}\n\t\t\n\t};\n\t\n\t#handleSessionDelete = (session: Session) => {\n\t\tconst wssc = this.#sessionsWsMap.get(session);\n\t\t\n\t\tif (wssc)\n\t\t\tthis.setSession(wssc, null);\n\t\t\n\t};\n\t\n\t#handleOrgsUpdate = () => {\n\t\t\n\t\tthis.orgsPublication.flushInitial();\n\t\tthis.orgsExtendedPublication.flushInitial();\n\t\t\n\t};\n\t\n\t#handleOrgsOrgUpdate = (org: Org, next: ChangeStreamDocument<OrgDoc>) => {\n\t\tif (next) {\n\t\t\tthis.orgsPublication.skip(next);\n\t\t\tthis.orgsExtendedPublication.skip(next);\n\t\t}\n\t\t\n\t};\n\t\n\t#handleUserPermissionsChange = (user: User) => {\n\t\tconst webSockets = this.#userWsMap.get(user);\n\t\t\n\t\tif (webSockets)\n\t\t\tthis.wss.emit(\"should-renew-subscriptions\", [ ...webSockets ]);\n\t\t\n\t};\n\t\n\t#handleClientRequestLogin = (wssc: WithUser<InSiteWebSocketServerClient, AS>, email: string, password: string) =>\n\t\tthis.#login(wssc, email, password);\n\t\n\t#handleClientRequestLogout = (wssc: WithUser<InSiteWebSocketServerClient, AS>) =>\n\t\tthis.#logout(wssc);\n\t\n\t#handleClientClosed = (wssc: WithUser<InSiteWebSocketServerClient, AS>) => {\n\t\twssc.session?.offline();\n\t\tthis.setSession(wssc, null);\n\t\t\n\t};\n\t\n\t\n\tstatic init<IAS extends AbilitiesSchema>(options: Options<IAS>) {\n\t\tconst usersServer = new UsersServer(options);\n\t\t\n\t\treturn usersServer.whenReady();\n\t}\n\t\n}\n", "import {\n\tCollectionMapPublication,\n\tProjection,\n\tPublication,\n\tSubscriptionHandle\n} from \"insite-subscriptions-server/ws\";\nimport {\n\t_ids,\n\tincludesAny,\n\tintersection,\n\tpick\n} from \"@nesvet/n\";\nimport { ChangeStreamDocument, Sort } from \"insite-db\";\nimport type {\n\tAbilitiesMap,\n\tAbilitiesSchema,\n\tOrgDoc,\n\tOrgs,\n\tRoleDoc,\n\tRoles,\n\tSessionDoc,\n\tSessions,\n\tUserDoc,\n\tUsers\n} from \"insite-users-server\";\n\n\nexport class AbilitiesPublication<AS extends AbilitiesSchema> extends Publication<AS> {\n\tconstructor(abilitiesMap: AbilitiesMap<AS>) {\n\t\tsuper(\"abilities\", {\n\t\t\t\n\t\t\tfetch(wssc) {\n\t\t\t\tif (wssc.user?.abilities.inSite?.sections?.includes(\"users\"))\n\t\t\t\t\treturn { abilities: abilitiesMap.getSchemeFor(wssc.user) };\n\t\t\t\t\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\t\n\t\t});\n\t}\n}\n\n\nexport type RolesPublicationOptions = {\n\tprojection?: Projection;\n\tsort?: Sort;\n\ttransform?: (roleDoc: object) => void;\n};\n\nexport class RolesPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<RoleDoc, AS> {\n\tconstructor(roles: Roles<AS>, options: RolesPublicationOptions = {}) {\n\t\t\n\t\tconst {\n\t\t\tprojection = { title: 1, description: 1 },\n\t\t\tsort = { _o: 1 },\n\t\t\ttransform\n\t\t} = options;\n\t\t\n\t\tObject.assign(projection, { involves: 1, abilities: 1 });\n\t\t\n\t\tsuper(\"roles\", roles.collection, wssc => wssc.user?.abilities.inSite?.sections?.includes(\"users\") && {\n\t\t\tquery: { _id: { $in: wssc.user.slaveRoleIds } },\n\t\t\tprojection,\n\t\t\tsort\n\t\t}, roleDoc => {\n\t\t\tconst { involves, abilities, inheritedAbilities, displayTitle, _o } = roles.get(roleDoc._id)!;\n\t\t\t\n\t\t\tObject.assign(roleDoc, {\n\t\t\t\t...roleDoc.involves ? {\n\t\t\t\t\townInvolves: roleDoc.involves,\n\t\t\t\t\tinvolves: _ids(involves),\n\t\t\t\t\tabilities,\n\t\t\t\t\tinheritedAbilities\n\t\t\t\t} : {},\n\t\t\t\t...projection.title ? { displayTitle } : {},\n\t\t\t\t_o\n\t\t\t});\n\t\t\t\n\t\t\ttransform?.(roleDoc);\n\t\t\t\n\t\t});\n\t\t\n\t}\n\t\n}\n\n\nconst userSubscriptionChangeListenerMap = new WeakMap<SubscriptionHandle, (next: ChangeStreamDocument<UserDoc>) => void>();\n\nexport type UserPublicationOptions = {\n\tfieldsToUpdate?: string[];\n\tprojection?: Projection;\n\ttransform?: (userDoc: object) => void;\n};\n\nexport class UserPublication<AS extends AbilitiesSchema> extends Publication<AS> {\n\tconstructor(users: Users<AS>, options: UserPublicationOptions = {}) {\n\t\t\n\t\tconst {\n\t\t\tfieldsToUpdate = [],\n\t\t\tprojection,\n\t\t\ttransform\n\t\t} = options;\n\t\t\n\t\tfor (const key of [\n\t\t\t\"email\",\n\t\t\t\"name\",\n\t\t\t\"name.first\",\n\t\t\t\"name.middle\",\n\t\t\t\"name.last\",\n\t\t\t\"org\",\n\t\t\t\"job\",\n\t\t\t\"avatar\"\n\t\t] as const)\n\t\t\tif (!projection || projection[key] !== 0)\n\t\t\t\tfieldsToUpdate.push(key);\n\t\t\n\t\tsuper(\"user\", {\n\t\t\t\n\t\t\tonSubscribe(subscription) {\n\t\t\t\tconst [ { user } ] = subscription.args;\n\t\t\t\t\n\t\t\t\tif (user) {\n\t\t\t\t\tconst { _id } = user;\n\t\t\t\t\t\n\t\t\t\t\tconst changeListener = (next: ChangeStreamDocument<UserDoc>) => {\n\t\t\t\t\t\tif (\"documentKey\" in next && next.documentKey._id === _id)\n\t\t\t\t\t\t\tswitch (next.operationType) {\n\t\t\t\t\t\t\t\tcase \"update\":\n\t\t\t\t\t\t\t\t\tif (!includesAny(Object.keys(next.updateDescription.updatedFields!), fieldsToUpdate))\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tcase \"replace\":// eslint-disable-line no-fallthrough\n\t\t\t\t\t\t\t\tcase \"delete\":\n\t\t\t\t\t\t\t\t\tsubscription.changed(next);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t};\n\t\t\t\t\t\n\t\t\t\t\tusers.collection.changeListeners.add(changeListener);\n\t\t\t\t\t\n\t\t\t\t\tuserSubscriptionChangeListenerMap.set(subscription, changeListener);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t},\n\t\t\t\n\t\t\tfetch({ user, session }, isSessionIdRequired) {\n\t\t\t\tif (user) {\n\t\t\t\t\tconst userDoc = pick(user, [\n\t\t\t\t\t\t\"_id\",\n\t\t\t\t\t\t\"email\",\n\t\t\t\t\t\t\"name\",\n\t\t\t\t\t\t\"initials\",\n\t\t\t\t\t\t\"displayLabel\",\n\t\t\t\t\t\t\"job\",\n\t\t\t\t\t\t\"avatarUrl\",\n\t\t\t\t\t\t\"abilities\",\n\t\t\t\t\t\t\"slaveIds\"\n\t\t\t\t\t]);\n\t\t\t\t\t\n\t\t\t\t\tObject.assign(userDoc, {\n\t\t\t\t\t\torgId: user.org._id,\n\t\t\t\t\t\tsessionId: isSessionIdRequired ? session?._id : undefined,\n\t\t\t\t\t\tisOnline: true\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tif (projection)\n\t\t\t\t\t\tfor (const key in projection)\n\t\t\t\t\t\t\tif (projection[key] && key in user)\n\t\t\t\t\t\t\t\tObject.assign(userDoc, { [key]: user[key as keyof typeof user] });\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tdelete userDoc[key as keyof typeof userDoc];\n\t\t\t\t\t\n\t\t\t\t\ttransform?.(userDoc);\n\t\t\t\t\t\n\t\t\t\t\treturn userDoc;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn null;\n\t\t\t},\n\t\t\t\n\t\t\tonUnsubscribe(subscription) {\n\t\t\t\tconst changeListener = userSubscriptionChangeListenerMap.get(subscription);\n\t\t\t\t\n\t\t\t\tif (changeListener)\n\t\t\t\t\tusers.collection.changeListeners.delete(changeListener);\n\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t});\n\t\t\n\t}\n}\n\n\nexport type UsersPublicationOptions = {\n\tprojection?: Projection;\n\tsort?: Sort;\n\ttransform?: (userDoc: object) => void;\n};\n\nexport class UsersPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<UserDoc, AS> {\n\tconstructor(users: Users<AS>, options: UsersPublicationOptions = {}) {\n\t\t\n\t\tconst {\n\t\t\tprojection = { email: 1, name: 1, org: 1, job: 1, avatar: 1 },\n\t\t\tsort = { \"name.last\": 1 },\n\t\t\ttransform\n\t\t} = options;\n\t\t\n\t\tsuper(\"users\", users.collection, wssc => wssc.user?.abilities.login && {\n\t\t\tquery: {},\n\t\t\tprojection,\n\t\t\tsort\n\t\t}, userDoc => {\n\t\t\t\n\t\t\tconst user = users.get(userDoc._id)!;\n\t\t\t\n\t\t\tObject.assign(\n\t\t\t\tuserDoc,\n\t\t\t\tpick(user, [\n\t\t\t\t\t\"initials\",\n\t\t\t\t\t\"displayLabel\",\n\t\t\t\t\t\"avatarUrl\",\n\t\t\t\t\t\"isOnline\"\n\t\t\t\t]),\n\t\t\t\t{ orgId: userDoc.org }\n\t\t\t);\n\t\t\t\n\t\t\tdelete userDoc.org;\n\t\t\tdelete userDoc.avatar;\n\t\t\t\n\t\t\ttransform?.(userDoc);\n\t\t\t\n\t\t});\n\t\t\n\t}\n}\n\n\nexport type UsersExtendedPublicationOptions = {\n\tprojection?: Projection;\n\tsort?: Sort;\n\ttriggers?: string[];\n\ttransform?: (userDoc: object) => void;\n};\n\nexport class UsersExtendedPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<UserDoc, AS> {\n\tconstructor(users: Users<AS>, options: UsersExtendedPublicationOptions = {}) {\n\t\t\n\t\tconst {\n\t\t\tprojection = { _id: 1 },\n\t\t\tsort,\n\t\t\ttriggers = [],\n\t\t\ttransform\n\t\t} = options;\n\t\t\n\t\tif (!triggers.includes(\"roles\"))\n\t\t\ttriggers.push(\"roles\");\n\t\t\n\t\tsuper(\"users.extended\", users.collection, wssc => wssc.user?.abilities.inSite?.sections?.includes(\"users\") && {\n\t\t\tquery: { _id: { $in: wssc.user.slaveIds } },\n\t\t\tprojection,\n\t\t\tsort,\n\t\t\ttriggers\n\t\t}, (userDoc, [ wssc ]) => {\n\t\t\tconst user = users.get(userDoc._id)!;\n\t\t\t\n\t\t\tObject.assign(userDoc, {\n\t\t\t\troleIds: intersection(user.ownRoleIds, wssc.user!.slaveRoleIds)\n\t\t\t});\n\t\t\t\n\t\t\ttransform?.(userDoc);\n\t\t\t\n\t\t});\n\t\t\n\t}\n}\n\n\nexport class SessionsPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<SessionDoc, AS, [ userId: string ]> {\n\tconstructor(sessions: Sessions<AS>) {\n\t\tsuper(\"users.people.sessions\", sessions.collection, (wssc, userId) =>\n\t\t\twssc.user?.abilities.inSite?.sections?.includes(\"users\") && wssc.user.permissiveIds.includes(userId) && {\n\t\t\t\tquery: { user: userId },\n\t\t\t\tprojection: { remoteAddress: 1, isOnline: 1, prolongedAt: 1 },\n\t\t\t\tsort: { prolongedAt: -1 }\n\t\t\t}\n\t\t);\n\t}\n}\n\n\nexport type OrgsPublicationOptions = {\n\tprojection?: Projection;\n\tsort?: Sort;\n\ttransform?: (orgDoc: object) => void;\n};\n\nexport class OrgsPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<OrgDoc, AS> {\n\tconstructor(orgs: Orgs, options: OrgsPublicationOptions = {}) {\n\t\t\n\t\tconst {\n\t\t\tprojection = { title: 1 },\n\t\t\tsort = { title: 1 },\n\t\t\ttransform\n\t\t} = options;\n\t\t\n\t\tsuper(\"orgs\", orgs.collection, wssc => wssc.user?.abilities.login && {\n\t\t\tquery: {},\n\t\t\tprojection,\n\t\t\tsort\n\t\t}, orgDoc => {\n\t\t\tconst org = orgs.get(orgDoc._id)!;\n\t\t\t\n\t\t\tObject.assign(orgDoc, pick(org, [ \"initials\", \"displayLabel\" ]));\n\t\t\t\n\t\t\ttransform?.(orgDoc);\n\t\t\t\n\t\t});\n\t\t\n\t}\n\t\n}\n\n\nexport type OrgsExtendedPublicationOptions = {\n\tprojection?: Projection;\n\tsort?: Sort;\n\ttriggers?: string[];\n\ttransform?: (orgDoc: object) => void;\n};\n\nexport class OrgsExtendedPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<OrgDoc, AS> {\n\tconstructor(orgs: Orgs<AS>, options: OrgsExtendedPublicationOptions = {}) {\n\t\t\n\t\tconst {\n\t\t\tprojection = { note: 1 },\n\t\t\tsort = { _o: 1 },\n\t\t\ttriggers = [],\n\t\t\ttransform\n\t\t} = options;\n\t\t\n\t\tif (!triggers.includes(\"owners\"))\n\t\t\ttriggers.push(\"owners\");\n\t\t\n\t\tsuper(\"orgs.extended\", orgs.collection, wssc => wssc.user?.abilities.inSite?.sections?.includes(\"users\") && {\n\t\t\tquery: { _id: { $in: wssc.user.slaveIds } },\n\t\t\tprojection,\n\t\t\tsort,\n\t\t\ttriggers\n\t\t}, (orgDoc, [ wssc ]) => {\n\t\t\tconst org = orgs.get(orgDoc._id)!;\n\t\t\t\n\t\t\tconst { ownerIds, slaveOrgs, _o } = org;\n\t\t\t\n\t\t\tObject.assign(orgDoc, {\n\t\t\t\towners: intersection(ownerIds, wssc.user!.slaveIds),\n\t\t\t\tslaveOrgs: _ids(intersection(slaveOrgs, wssc.user!.slaveOrgs)),\n\t\t\t\t_o\n\t\t\t});\n\t\t\t\n\t\t\ttransform?.(orgDoc);\n\t\t\t\n\t\t});\n\t\t\n\t}\n\t\n}\n", "export const regexps = {\n\temail: /^[^\\s@]{1,63}@[^\\s@]{1,63}\\.[^\\s@]{1,63}$/,\n\trole: /^[\\d_a-z-]{1,64}$/\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["_ids", "Err", "includesAll", "isEmpty", "removeAll", "union", "without", "Binary", "Users", "CollectionMapPublication", "Publication", "_ids", "includesAny", "intersection", "pick", "AbilitiesPublication", "abilitiesMap", "wssc", "RolesPublication", "roles", "options", "projection", "sort", "transform", "roleDoc", "involves", "abilities", "inheritedAbilities", "displayTitle", "_o", "userSubscriptionChangeListenerMap", "UserPublication", "users", "fieldsToUpdate", "key", "subscription", "user", "_id", "changeListener", "next", "session", "isSessionIdRequired", "userDoc", "UsersPublication", "UsersExtendedPublication", "triggers", "SessionsPublication", "sessions", "userId", "OrgsPublication", "orgs", "orgDoc", "org", "OrgsExtendedPublication", "ownerIds", "slaveOrgs", "regexps", "avatarTypesAccepted", "maxAvatarSize", "UsersServer", "_UsersServer", "options", "#initPromise", "#userWsMap", "#sessionsWsMap", "wss", "collections", "usersOptions", "publicationOptions", "extendedPublicationOptions", "userPublicationOptions", "rolesOptions", "orgsOptions", "getSessionProps", "incomingTransport", "rolesPublicationOptions", "orgsPublicationOptions", "orgsExtendedPublicationOptions", "Users", "user", "#handleUserCreate", "AbilitiesPublication", "RolesPublication", "UsersPublication", "UsersExtendedPublication", "UserPublication", "OrgsPublication", "OrgsExtendedPublication", "SessionsPublication", "#handleRolesUpdate", "#handleRolesRoleUpdate", "#handleUserIsOnline", "#handleSessionDelete", "#handleOrgsUpdate", "#handleOrgsOrgUpdate", "#handleUserPermissionsChange", "#handleClientRequestLogin", "#handleClientRequestLogout", "#handleClientClosed", "wssc", "email", "regexps", "Err", "roles", "org", "rest", "includesAll", "_id", "newPassword", "updates", "without", "isEmpty", "sessionId", "getAvatarTransferProps", "check", "transfer", "data", "type", "binaryData", "Binary", "ts", "deleteAvatar", "union", "_ids", "role", "abilities", "removeAll", "involvedRoleId", "abilityId", "paramId", "value", "shouldUpdate", "param", "anotherParam", "userAbilityWithParams", "abilityWithParams", "resolve", "schema", "subSchema", "userAgent", "remoteAddress", "session", "shouldProlong", "#login", "password", "#logout", "next", "isOnline", "usersSubscription", "webSockets"]
7
+ }
@@ -0,0 +1,60 @@
1
+ import { CollectionMapPublication, Projection, Publication } from "insite-subscriptions-server/ws";
2
+ import { Sort } from "insite-db";
3
+ import type { AbilitiesMap, AbilitiesSchema, OrgDoc, Orgs, RoleDoc, Roles, SessionDoc, Sessions, UserDoc, Users } from "insite-users-server";
4
+ export declare class AbilitiesPublication<AS extends AbilitiesSchema> extends Publication<AS> {
5
+ constructor(abilitiesMap: AbilitiesMap<AS>);
6
+ }
7
+ export type RolesPublicationOptions = {
8
+ projection?: Projection;
9
+ sort?: Sort;
10
+ transform?: (roleDoc: object) => void;
11
+ };
12
+ export declare class RolesPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<RoleDoc, AS> {
13
+ constructor(roles: Roles<AS>, options?: RolesPublicationOptions);
14
+ }
15
+ export type UserPublicationOptions = {
16
+ fieldsToUpdate?: string[];
17
+ projection?: Projection;
18
+ transform?: (userDoc: object) => void;
19
+ };
20
+ export declare class UserPublication<AS extends AbilitiesSchema> extends Publication<AS> {
21
+ constructor(users: Users<AS>, options?: UserPublicationOptions);
22
+ }
23
+ export type UsersPublicationOptions = {
24
+ projection?: Projection;
25
+ sort?: Sort;
26
+ transform?: (userDoc: object) => void;
27
+ };
28
+ export declare class UsersPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<UserDoc, AS> {
29
+ constructor(users: Users<AS>, options?: UsersPublicationOptions);
30
+ }
31
+ export type UsersExtendedPublicationOptions = {
32
+ projection?: Projection;
33
+ sort?: Sort;
34
+ triggers?: string[];
35
+ transform?: (userDoc: object) => void;
36
+ };
37
+ export declare class UsersExtendedPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<UserDoc, AS> {
38
+ constructor(users: Users<AS>, options?: UsersExtendedPublicationOptions);
39
+ }
40
+ export declare class SessionsPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<SessionDoc, AS, [userId: string]> {
41
+ constructor(sessions: Sessions<AS>);
42
+ }
43
+ export type OrgsPublicationOptions = {
44
+ projection?: Projection;
45
+ sort?: Sort;
46
+ transform?: (orgDoc: object) => void;
47
+ };
48
+ export declare class OrgsPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<OrgDoc, AS> {
49
+ constructor(orgs: Orgs, options?: OrgsPublicationOptions);
50
+ }
51
+ export type OrgsExtendedPublicationOptions = {
52
+ projection?: Projection;
53
+ sort?: Sort;
54
+ triggers?: string[];
55
+ transform?: (orgDoc: object) => void;
56
+ };
57
+ export declare class OrgsExtendedPublication<AS extends AbilitiesSchema> extends CollectionMapPublication<OrgDoc, AS> {
58
+ constructor(orgs: Orgs<AS>, options?: OrgsExtendedPublicationOptions);
59
+ }
60
+ //# sourceMappingURL=publications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publications.d.ts","sourceRoot":"","sources":["../src/publications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const regexps: {
2
+ email: RegExp;
3
+ role: RegExp;
4
+ };
5
+ //# sourceMappingURL=regexps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regexps.d.ts","sourceRoot":"","sources":["../src/regexps.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO;;;CAGnB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "insite-users-server-ws",
3
+ "version": "2.0.0",
4
+ "description": "inSite users server side WebSocket API",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "packageManager": "bun@1.1.21",
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1",
11
+ "build": "bun .conveyer.js",
12
+ "postbuild": "tsc -p ."
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/nesvet/insite-users-server-ws.git"
17
+ },
18
+ "keywords": [
19
+ "insite",
20
+ "users",
21
+ "server",
22
+ "ws"
23
+ ],
24
+ "author": "Eugene Nesvetaev <dev@nesvet.dev> (https://nesvet.dev/)",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "@nesvet/n": "^1.1.1",
28
+ "insite-db": "^2.0.0",
29
+ "insite-users-server": "^2.0.0",
30
+ "insite-subscriptions-server": "^2.0.1"
31
+ },
32
+ "devDependencies": {
33
+ "@nesvet/conveyer": "^2.2.1",
34
+ "@nesvet/eslint-config": "^2.0.24",
35
+ "@types/node": "^20.14.13",
36
+ "@types/ws": "^8.5.12",
37
+ "insite-ws": "^2.0.9",
38
+ "insite-ws-transfers": "^2.0.3",
39
+ "typescript": "^5.5.4"
40
+ }
41
+ }