HEX
Server: nginx/1.24.0
System: Linux nowruzgan 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025 x86_64
User: babak (1000)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/dev/nowruzgan/ketabkhaneh/src/app/data.types.ts
import { environment } from "../environments/environment";

export type LangString = {fa?: string, en?: string};

export type ReferenceMap = {
  file: string,
  name: string
};
export type ReferencedDoc = {
  id: number,
  map: string,
  location: {
    x: number,
    y: number
  }[]
};

export class Entity {
  constructor(data?: any) {
    if(data) this.absorb(data);
  }

  absorb(data: any) {
    if(typeof data == 'number' || typeof data == 'string') {
      (this as any).id = data;
      return;
    }
    for(let key in data) (this as any)[key] = data[key];
  }

  meta: any = {};
}

export class Batch<T extends Entity> {
  limit: number = 0;
  sum: number = 0;
  totalPages: number = 0;
  offset: number = 0;
  filter: string = '';
  constraints: any = {};
  meta: any = {};
  sort: string = "createdAt desc";
  list: T[] = [];
  private _page: number = 0;

  set page(v: number) {
    this._page = v;
    this.offset = this.limit*this._page;
  }

  get page(): number {
    return this._page;
  }

  constructor(private type: { new(data?: any): T ;}, offset?: number, limit?: number) {
    this.limit = limit || this.limit;
    this.offset = offset || this.offset;
  }

  remove(m: T) {
    this.list = this.list.filter(el => (el as any).id!=(m as any).id)
  }

  absorb(batchData: any) {
    this.sum = batchData.sum;
    this.totalPages = Math.ceil(batchData.sum/this.limit);
    batchData.list.map((item: any) => new this.type(item));
    this.list = [...this.list, ...batchData.list.map((item: any) => new this.type(item))];
  }
}

export class Media extends Entity {
  constructor(data?: any) {
    super(data);
    if(data) this.absorb(data);
  }

  id: number = 0;
  uuid: string = '';
  fname: string = '';
  size: number = 0;
  type: string = '';
  wordRef: string = '';
  caption: string = '';

  get ext(): string {
    if(!this.fname)
      return '';
    else
      return this.fname.split('.').pop() || '';
  }

  get url(): string {
    if(!this.uuid) return '';
    let _url = `/static/${this.uuid.substr(0, 2)}/${this.uuid}`;
    let fileName = this.meta.fileName || this.fname || '';
    fileName = fileName.replace(/[ \(\)\[\]\{\}]/g, '_').replace(/__+/g, '_');
    if(fileName)
      _url += `/${fileName}`;
    return _url;
  }
}

export class Tag extends Entity {
  constructor(data?: any) {
    super(data);
    if(data) this.postAbsorb(data);
  }

  postAbsorb(data: any) {
    super.absorb(data);

    this.meta.sources = (data.sources as string || '').split(',').map(i => parseInt(i));
    delete (this as any).sources;

    if(data.docs)
      this.docs = data.docs.map((record: number) => new Doc(record));

    this.meta.published = data.published || 0;
    this.meta.total = data.total || 0;
  }

  id: number = 0;
  title: LangString = {en: '', fa: ''};
  taxonomy: string = '';
  docs: Doc[] = [];
  count: number = 0;
}

export class Collection extends Entity {
  constructor(data?: any) {
    super(data);
    if(data) this.postAbsorb(data);
  }

  postAbsorb(data: any) {
    super.absorb(data);
    if(data.createdAt) this.createdAt = new Date(data.createdAt);
    if(data.updatedAt) this.updatedAt = new Date(data.updatedAt);

    if(data.categories)
      this.categories = data.categories.map((cat: any) => new Tag(cat));
    if(this.properties.refMap)
      this.properties.refMaps = [this.properties.refMap].flat();
    else
      this.properties.refMaps = [];
  }

  id: number = 0;
  title: LangString = {en: '', fa: ''};
  desc: LangString = {en: '', fa: ''};
  slug: string = '';
  order: number = 0;
  state: string = '';
  createdAt?: Date;
  updatedAt?: Date;
  properties: any = {};
  cover: Doc = new Doc({id: 'cover', collection: this});
  categories: Tag[] = [];
}

export class Doc extends Entity {
  constructor(data?: any) {
    super(data);
    if(data) this.postAbsorb(data);
  }

  postAbsorb(data: any) {
    super.absorb(data);

    if(data.createdAt) this.createdAt = new Date(data.createdAt);
    if(data.updatedAt) this.updatedAt = new Date(data.updatedAt);
    if(data.collection && !(data.collection instanceof Collection))
      this.collection = new Collection(data.collection);
    if(data.tags) this.tags = data.tags.map((tagData: any) => new Tag(tagData));
    if(data.cats) this.cats = data.cats.map((tagData: any) => new Tag(tagData));

    if(!this.properties.altNames)
      this.properties.altNames = [];
    if(typeof this.properties.altNames == 'string')
      this.properties.altNames = [this.properties.altNames];
    this.properties.altNames = this.properties.altNames
      .map((alt: string) => ({name: alt.trim()}))
      .filter((alt: any) => alt.name.length);

    if(!this.properties.set_altNames)
      this.properties.set_altNames = [];
    if(typeof this.properties.set_altNames == 'string')
      this.properties.set_altNames = [this.properties.set_altNames];
    this.properties.set_altNames = this.properties.set_altNames
      .map((alt: string) => ({name: alt.trim()}))
      .filter((alt: any) => alt.name.length);

    if(data.set)
      this.set = data.set.map((_doc: any) => new Doc({..._doc, meta: {setMember: true}}));

    if(data.next && !(data.next instanceof Doc)) this.next = new Doc(data.next);
    if(data.prev && !(data.prev instanceof Doc)) this.prev = new Doc(data.prev);
  }

  get thumb(): string {
    if(this.collection)
      return environment.imageBase
                        .replace('{COLLECTION}', this.collection.slug)
                        .replace('{ID}', `${this.id}`)
                        +'/square/512,/0/default.jpg';
    return '';
  }

  get cover(): string {
    if(this.collection)
      return environment.imageBase
                        .replace('{COLLECTION}', this.collection.slug)
                        .replace('{ID}', `${this.id}`)
                        +'/full/1200,/0/default.jpg';
    return '';
  }

  get original(): string {
    if(this.collection)
      return environment.imageBase
                        .replace('{COLLECTION}', this.collection.slug)
                        .replace('{ID}', `${this.id}`)
                        +'/full/max/0/default.jpg';
    return '';
  }

  get downloadUrl(): string {
    if(this.collection)
      return `${this.original}/ketabkhaneh_${this.collection.slug}_${this.id}.jpg`
    return '';
  }

  id: number|string = 0;
  docType: string = '';
  docSubType: string = '';
  contentType: string = '';
  title: LangString = {fa: '', en: ''};
  state: string = '';
  setId: number = 0;
  setOrder: number = 0;
  setCount: number = 0;
  set: Doc[] = [];
  collection?: Collection;
  desc: LangString = {fa: '', en: ''};
  properties: any = {};
  createdAt?: Date;
  updatedAt?: Date;
  tags: Tag[] = [];
  cats: Tag[] = [];

  prev?: Doc;
  next?: Doc;
}