Skip to content

Commit

Permalink
Merge pull request #40 from tsaxking/chore-update-scripts-to-7278a79b…
Browse files Browse the repository at this point in the history
…d18209e0d86c3ad10b185556c54e18be

Chore update scripts to 7278a79
  • Loading branch information
tsaxking authored Feb 2, 2024
2 parents 021cf4c + 10e00f9 commit 32aa7e1
Show file tree
Hide file tree
Showing 34 changed files with 806 additions and 178 deletions.
4 changes: 4 additions & 0 deletions client/entries/dashboard/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import '../../utilities/imports';
import App from '../../views/dashboards/User.svelte';

const myApp = new App({ target: document.body });
28 changes: 28 additions & 0 deletions client/entries/test/role-badge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Account } from '../../models/account';
import { Role } from '../../models/roles';
import '../../utilities/imports';
import App from '../../views/components/accounts/RoleBadge.svelte';

const myApp = new App({
target: document.body,
props: {
account: new Account({
id: '1',
username: 'test',
email: '',
firstName: '',
lastName: '',
verified: 1,
created: Date.now(),
phoneNumber: '',
picture: '',
}),
role: new Role({
id: '1',
name: 'Test',
description: 'Test',
rank: 1,
}),
deletable: true,
},
});
137 changes: 119 additions & 18 deletions client/models/account.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { EventEmitter } from '../../shared/event-emitter';
import { Cache } from './cache';
import { AccountSafe, Role as R } from '../../shared/db-types';
import { Permission as P } from '../../shared/permissions';
import { Permission as P, RoleName } from '../../shared/permissions';
import { attemptAsync, Result } from '../../shared/attempt';
import { ServerRequest } from '../utilities/requests';
import { Role } from './roles';
import { socket } from '../utilities/socket';

/**
* All account events
Expand All @@ -14,6 +15,9 @@ import { Role } from './roles';
*/
type Events = {
new: Account;
update: Account;
delete: Account;
current: Account;
};

/**
Expand All @@ -23,7 +27,12 @@ type Events = {
* @typedef {AccountEvents}
*/
type AccountEvents = {
update: Account;
update: undefined;
delete: undefined;
'role-added': string;
'role-removed': string;
verified: Account;
unverified: Account;
};

/**
Expand All @@ -36,6 +45,27 @@ type AccountEvents = {
* @extends {Cache<AccountEvents>}
*/
export class Account extends Cache<AccountEvents> {
/**
* Cache of all accounts
* @date 2/1/2024 - 12:54:21 AM
*
* @public
* @static
* @readonly
* @type {*}
*/
public static readonly $cache = new Map<string, Account>();
public static readonly guest = new Account({
id: 'guest',
username: 'guest',
firstName: 'Guest',
lastName: 'User',
email: '',
verified: 0,
created: Date.now(),
phoneNumber: '',
});

/**
* Current account, if any
* @date 2/1/2024 - 12:54:21 AM
Expand Down Expand Up @@ -118,7 +148,11 @@ export class Account extends Cache<AccountEvents> {
*/
public static async all(): Promise<Result<Account[]>> {
return attemptAsync(async () => {
const res = await ServerRequest.get<AccountSafe[]>('/account/all');
if (Account.$cache.size > 0) {
return Array.from(Account.$cache.values());
}

const res = await ServerRequest.post<AccountSafe[]>('/account/all');

if (res.isOk()) {
return res.value.map((account) => new Account(account));
Expand All @@ -128,17 +162,6 @@ export class Account extends Cache<AccountEvents> {
});
}

/**
* Cache of all accounts
* @date 2/1/2024 - 12:54:21 AM
*
* @public
* @static
* @readonly
* @type {*}
*/
public static readonly $cache = new Map<string, Account>();

/**
* Account id
* @date 2/1/2024 - 12:54:21 AM
Expand Down Expand Up @@ -247,14 +270,20 @@ export class Account extends Cache<AccountEvents> {
* @async
* @returns {Promise<Result<Role[]>>}
*/
public async getRoles(): Promise<Result<Role[]>> {
public async getRoles(force = false): Promise<Result<Role[]>> {
return attemptAsync(async () => {
if (this.$cache.has('roles') && !force) {
return this.$cache.get('roles') as Role[];
}

const res = await ServerRequest.post<R[]>('/account/get-roles', {
id: this.id,
});

if (res.isOk()) {
return res.value.map((r) => new Role(r));
const roles = res.value.map((r) => new Role(r));
this.$cache.set('roles', roles);
return roles;
}

throw res.error;
Expand All @@ -269,8 +298,12 @@ export class Account extends Cache<AccountEvents> {
* @async
* @returns {Promise<Result<P[]>>}
*/
public async getPermissions(): Promise<Result<P[]>> {
public async getPermissions(force = false): Promise<Result<P[]>> {
return attemptAsync(async () => {
if (this.$cache.has('permissions') && !force) {
return this.$cache.get('permissions') as P[];
}

const res = await ServerRequest.post<P[]>(
'/account/get-permissions',
{
Expand All @@ -279,7 +312,9 @@ export class Account extends Cache<AccountEvents> {
);

if (res.isOk()) {
return res.value;
const permissions = res.value;
this.$cache.set('permissions', permissions);
return permissions;
}

throw res.error;
Expand Down Expand Up @@ -427,3 +462,69 @@ export class Account extends Cache<AccountEvents> {
});
}
}

socket.on('account:removed', (accountId: string) => {
const account = Account.$cache.get(accountId);
Account.$cache.delete(accountId);
if (account) {
console.log('account removed', account);
Account.emit('delete', account);
account.emit('delete', undefined);
account.destroy();
}
});

socket.on('account:created', (account: AccountSafe) => {
const a = new Account(account);
Account.emit('new', a);
});

socket.on('account:role-removed', async (accountId: string, roleId: string) => {
const account = Account.$cache.get(accountId);
if (account) {
await account.getRoles(true); // force update

account.emit('update', undefined);
account.emit('role-removed', roleId);
Account.emit('update', account);
}
});

socket.on('account:role-added', async (accountId: string, roleId: string) => {
const account = Account.$cache.get(accountId);
if (account) {
await account.getRoles(true); // force update

account.emit('update', undefined);
account.emit('role-added', roleId);
Account.emit('update', account);
}
});

socket.on('account:verified', (accountId: string) => {
const account = Account.$cache.get(accountId);
if (account) {
account.verified = 1;
account.emit('verified', account);
account.emit('update', undefined);
Account.emit('update', account);
}
});

socket.on('account:unverified', (accountId: string) => {
const account = Account.$cache.get(accountId);
if (account) {
account.verified = 0;
account.emit('unverified', account);
account.emit('update', undefined);
Account.emit('update', account);
}
});

ServerRequest.post<AccountSafe>('/account/get-account').then((res) => {
if (res.isOk()) {
Account.current = new Account(res.value);
Account.emit('current', Account.current);
console.log('current account', Account.current);
}
});
87 changes: 86 additions & 1 deletion client/models/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,46 @@ import { ServerRequest } from '../utilities/requests';
import { Role as R } from '../../shared/db-types';
import { attemptAsync, Result } from '../../shared/attempt';
import { Cache } from './cache';
import { Permission } from '../../shared/permissions';
import { EventEmitter } from '../../shared/event-emitter';

type Events = {
new: Role;
delete: Role;
update: Role;
};

export class Role extends Cache<Events> {
type RoleEvents = {
new: Role;
delete: Role;
update: Role;
'add-permission': Permission;
'remove-permission': Permission;
};

export class Role extends Cache<RoleEvents> {
private static readonly roles: Role[] = [];

static readonly $emitter = new EventEmitter<keyof Events>();

static on<E extends keyof Events>(
event: E,
listener: (data: Events[E]) => void,
) {
Role.$emitter.on(event, listener);
}

static off<E extends keyof Events>(
event: E,
listener: (data: Events[E]) => void,
) {
Role.$emitter.off(event, listener);
}

static emit<E extends keyof Events>(event: E, data: Events[E]) {
Role.$emitter.emit(event, data);
}

static async all(): Promise<Result<Role[]>> {
return attemptAsync(async () => {
if (Role.roles.length) {
Expand All @@ -29,6 +61,33 @@ export class Role extends Cache<Events> {
});
}

static async new(data: {
name: string;
description: string;
}): Promise<Result<Role>> {
return attemptAsync(async () => {
const { name, description } = data;
const role = await ServerRequest.post<R>('/roles/new', {
name,
description,
});

if (role.isOk()) {
return new Role(role.value);
}

throw role.error;
});
}

static async delete(role: Role): Promise<Result<Role>> {
return attemptAsync(async () => {
Role.roles.splice(Role.roles.indexOf(role), 1);
Role.emit('delete', role);
return role;
});
}

public readonly id: string;
public readonly name: string;
public readonly description: string;
Expand All @@ -45,4 +104,30 @@ export class Role extends Cache<Events> {
Role.roles.push(this);
}
}

async addPermission(permission: Permission): Promise<Result<void>> {
return attemptAsync(async () => {
await ServerRequest.post<void>('/roles/add-permission', {
roleId: this.id,
permission,
});
this.emit('add-permission', permission);
});
}

async removePermission(permission: Permission): Promise<Result<void>> {
return attemptAsync(async () => {
await ServerRequest.post<void>('/roles/remove-permission', {
roleId: this.id,
permission,
});
this.emit('remove-permission', permission);
});
}

getPermissions(): Promise<Result<Permission[]>> {
return ServerRequest.post<Permission[]>(`/roles/permissions`, {
roleId: this.id,
});
}
}
Empty file.
Loading

0 comments on commit 32aa7e1

Please sign in to comment.