0.1.0Updated a month ago
// deno-lint-ignore-file no-explicit-any

import { RequestManager } from "../modules/api/request.ts";
import { GetDracoUser } from "../modules/api/user.ts";

interface DracoOptions {
  host?: string
  api_key?: string
  permissions: Record<string, any>
}

export class Draco {
  private static _HOST: string
  private static _API_KEY: string
  private static _PERMISSIONS: Record<string, any>

  private static _initialized = false

  static get HOST() { return this._HOST }
  static get API_KEY() { return this._API_KEY }
  static get PERMISSIONS() { return this._PERMISSIONS }

  private static request_manager = new RequestManager(this);

  constructor(readonly user: Draco.User | null) {}

  static Request<T = any>(...params: Parameters<RequestManager['Send']>) {
    if(!this._initialized) throw new Error('Draco not configured. [Draco.Configure()]');

    return this.request_manager.Send<T>(...params);
  }

  static Configure(options: DracoOptions) {
    this._HOST = options.host || Deno.env.get('DRACO_HOST') || Deno.env.get('DRACO_URL')!;
    this._API_KEY = options.api_key || Deno.env.get('DRACO_API_KEY')!;
    this._PERMISSIONS = Object.freeze(options.permissions);

    if(!this.HOST) throw new Error('Draco host not set');
    if(!this.API_KEY) throw new Error('Draco api key not set');

    this._initialized = true;
  }

  static async Handler(cookie_uuid: string, ctx: Draco.Context) {
    const draco_user = await GetDracoUser(this, cookie_uuid);

    if(draco_user) {
      ctx.state.draco_user = draco_user;
    }

    ctx.draco = new Draco(ctx.state.draco_user || null);
  }

  get is_super_admin() {
    return this.user?.permissions.includes('*') || false;
  }

  can(permission: string) {
    if(!this.user) return false;
    if(this.is_super_admin) return true;

    return this.user.permissions.includes(permission);
  }

  has_permission(permission: string) {
    if(!this.user) return false;
    if(this.is_super_admin) return true;

    return this.user.permissions.includes(permission);
  }

  has_one_permission_of(...permissions: string[]) {
    if(!this.user) return false;
    if(this.is_super_admin) return true;

    return permissions.some(permission => this.user!.permissions.includes(permission));
  }

  has_all_permission_of(...permissions: string[]) {
    if(!this.user) return false;
    if(this.is_super_admin) return true;
    
    return permissions.every(permission => this.user!.permissions.includes(permission));
  }
}