From 63af020a3038a4f92947fd6f2343d4f65c7ac691 Mon Sep 17 00:00:00 2001 From: pxseu <57842793+pxseu@users.noreply.github.com> Date: Mon, 1 Nov 2021 14:45:40 +0100 Subject: [PATCH] feat(classes): make classes inherit more from base --- src/lib/classes/Base.ts | 21 +++++-- src/lib/classes/Document/Settings.ts | 16 ++++-- src/lib/classes/Document/Timestamps.ts | 13 ++++- src/lib/classes/Document/index.ts | 32 ++++++++--- src/lib/classes/User.ts | 78 ++++++++++++++++++++++++++ src/lib/classes/index.ts | 3 + 6 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 src/lib/classes/User.ts diff --git a/src/lib/classes/Base.ts b/src/lib/classes/Base.ts index b65452d..9346586 100644 --- a/src/lib/classes/Base.ts +++ b/src/lib/classes/Base.ts @@ -1,7 +1,7 @@ import { objectify } from "../utils/objectify"; -import type { Imperial } from "../client/Imperial"; +import type { Imperial } from "../client"; -export abstract class Base { +export abstract class Base { constructor(client: Imperial) { Object.defineProperty(this, "client", { value: client }); } @@ -17,25 +17,34 @@ export abstract class Base { * @internal */ // eslint-disable-next-line class-methods-use-this - public _patch(data: any) { + public _patch(data: T): T { return data; } /** * @internal */ - public _update(data: unknown): this { + public _update(data: T): this { const clone = this._clone(); this._patch(data); return clone; } - public toJSON(...props: Parameters[1][]) { + /** + * Convert the class to a plain object + * @param props - Properties to exclude from the object + * @example + * console.log(someclass.toJSON()) + * > { id: 'abc123', content: "hello" } + */ + + public toJSON(...props: Parameters[1][]): T { // a little hack so typing do not yell at me return objectify(this as Record, ...props); } } -export interface Base { +// eslint-disable-next-line +export interface Base { readonly client: Imperial; } diff --git a/src/lib/classes/Document/Settings.ts b/src/lib/classes/Document/Settings.ts index 5f8fa52..ba118f5 100644 --- a/src/lib/classes/Document/Settings.ts +++ b/src/lib/classes/Document/Settings.ts @@ -2,7 +2,7 @@ import type { Imperial } from "../.."; import type { Settings as ISettings } from "../../types/document"; import { Base } from "../Base"; -export class Settings extends Base { +export class Settings extends Base { constructor(client: Imperial, settings: ISettings) { super(client); @@ -58,11 +58,17 @@ export class Settings extends Base { // @ts-ignore this.imageEmbed = false; } - } - public toJSON() { - return super.toJSON(); + return settings; } } -export interface Settings extends ISettings {} +export interface Settings { + language: string; + imageEmbed: boolean; + instantDelete: boolean; + encrypted: boolean; + password: string | null; + public: boolean; + editors: string[]; +} diff --git a/src/lib/classes/Document/Timestamps.ts b/src/lib/classes/Document/Timestamps.ts index 1c7a39b..435cfe5 100644 --- a/src/lib/classes/Document/Timestamps.ts +++ b/src/lib/classes/Document/Timestamps.ts @@ -3,7 +3,7 @@ import type { Timestamps as ITimeStamps } from "../../types/document"; import { getDateDifference } from "../../utils/dateDifference"; import { Base } from "../Base"; -export class Timestamps extends Base { +export class Timestamps extends Base { constructor(client: Imperial, timestamps: ITimeStamps) { super(client); @@ -23,16 +23,27 @@ export class Timestamps extends Base { if ("expiration" in timestamps) { this.expiration = new Date(timestamps.expiration * 1000); } + + return timestamps; } /** * The ammount of days the Doucment will expire at from the current moment + * @returns {number} The ammount of days the Document will expire at from the current moment */ public get daysLeft(): number | null { const daysLeft = getDateDifference(new Date(), this.expiration); if (daysLeft <= 0) return null; return daysLeft; } + + /** + * The ammount of days the Document will expire at from it's creation date + * @returns {number} The ammount of days the Document will expire at from it's creation date + */ + public get expirationDays(): number { + return getDateDifference(this.creation, this.expiration); + } } export interface Timestamps { diff --git a/src/lib/classes/Document/index.ts b/src/lib/classes/Document/index.ts index e0d732e..9a1d1b2 100644 --- a/src/lib/classes/Document/index.ts +++ b/src/lib/classes/Document/index.ts @@ -1,8 +1,8 @@ import type { Document as IDocument, DocumentEditOptions } from "../../types/document"; import { createFormatedLink, createRawLink } from "../../utils/links"; import { Base } from "../Base"; -import type { Imperial } from "../../client/Imperial"; -import { DocumentNotFound } from "../../errors/Imperial/DocumentNotFound"; +import type { Imperial } from "../../client"; +import { NotFound } from "../../errors/Imperial/NotFound"; import { Settings } from "./Settings"; import { Timestamps } from "./Timestamps"; /** @@ -10,7 +10,7 @@ import { Timestamps } from "./Timestamps"; * All data from the Document can be accesed here * @author pxseu & hexiro */ -export class Document extends Base { +export class Document extends Base { constructor(client: Imperial, document: IDocument) { super(client); @@ -46,19 +46,23 @@ export class Document extends Base { if ("timestamps" in document) { this.timestamps = new Timestamps(this.client, document.timestamps); } + + return document; } /** * URL of the Document, to view in Imperial + * @returns {string} The url in format https://{hostname}/{id} */ - public get link(): string { + public get formatted(): string { return createFormatedLink(this.client, this.id); } /** * URL to a plain text version of the Document + * @returns {string} The url in format https://{hostname}/r/{id} */ - public get rawLink(): string { + public get raw(): string { return createRawLink(this.client, this.id); } @@ -83,7 +87,7 @@ export class Document extends Base { * @returns Deleted Document */ public async delete(): Promise { - if (this.deleted) throw new DocumentNotFound(); + if (this.deleted) throw new NotFound(); await this.client.document.delete(this.id); @@ -124,7 +128,7 @@ export class Document extends Base { * @returns Edited Document */ public async edit(text: string): Promise { - if (this.deleted) throw new DocumentNotFound(); + if (this.deleted) throw new NotFound(); const document = await this.client.document.edit(this.id, text); @@ -133,6 +137,16 @@ export class Document extends Base { return old; } + /** + * Revalidate the Document + * @returns Current document + */ + public async revalidate(): Promise { + const data = await this.client.document.get(this.id); + this._update(data.toJSON()); + return this; + } + /** * Concatonate the content insted of the object */ @@ -145,6 +159,8 @@ export class Document extends Base { */ public toJSON() { return super.toJSON({ + longerUrls: true, + shortUrls: true, deleted: false, }); } @@ -178,7 +194,7 @@ export interface Document { views: number; /** - * Whether this Document has been deleted + * Internal value to track if this current object had the .delete method called */ deleted: boolean; diff --git a/src/lib/classes/User.ts b/src/lib/classes/User.ts new file mode 100644 index 0000000..9cd3a3b --- /dev/null +++ b/src/lib/classes/User.ts @@ -0,0 +1,78 @@ +import type { Imperial } from "../client"; +import type { User as IUser } from "../types/users"; +import { Base } from "./Base"; + +export class User extends Base { + constructor(client: Imperial, user: IUser) { + super(client); + + if (!user) throw new Error("User: No data provided"); + + this._patch(user); + } + + /** + * @internal + */ + public _patch(user: IUser) { + if ("username" in user) { + this.username = user.username; + } else if (typeof user.username !== "string") { + // @ts-ignore + this.username = null; + } + + if ("memberPlus" in user) { + this.memberPlus = user.memberPlus; + } else if (typeof user.memberPlus !== "boolean") { + this.memberPlus = false; + } + + if ("icon" in user) { + this.icon = user.icon; + } else if (typeof user.icon !== "string") { + this.icon = "/assets/img/pfp.png"; + } + + if ("banned" in user) { + this.banned = user.banned; + } else if (typeof user.banned !== "boolean") { + this.banned = false; + } + + return user; + } + + /** + * Revalidate the user + * @example user.revalidate().then(console.log); + * + */ + public async revalidate(): Promise { + const user = this._clone(); + const data = await this.client.users.get(user.username); + user._patch(data); + return user; + } + + /** + * Concatonate the username insted of the object + */ + public toString() { + return this.username; + } + + /** + * Convert the user to a JSON object + */ + public toJSON() { + return super.toJSON(); + } +} + +export interface User { + username: string; + icon: string; + memberPlus: boolean; + banned: boolean; +} diff --git a/src/lib/classes/index.ts b/src/lib/classes/index.ts index 08b27fa..edbc867 100644 --- a/src/lib/classes/index.ts +++ b/src/lib/classes/index.ts @@ -1 +1,4 @@ export { Document } from "./Document"; +export { User } from "./User"; +export { Settings } from "./Document/Settings"; +export { Timestamps } from "./Document/Timestamps";