A powerful and extendable Discord bot, with it's own module system :3
thevoid.cafe/projects/voidy
1//===============================================
2// Imports
3//===============================================
4import { Glob } from "bun";
5
6//===============================================
7// Loader Definition
8//===============================================
9interface ILoader<T extends object> {
10 id: string;
11 cache: T[];
12 source: string;
13
14 collect: () => Promise<ThisType<this>>;
15 validate: (data: Partial<T>) => Promise<T | null>;
16 getJSON: () => T[];
17}
18
19//===============================================
20// Loader Implementation
21//===============================================
22export abstract class Loader<T extends object> implements ILoader<T> {
23 public abstract id: string;
24 public cache: T[] = [];
25 public source: string;
26
27 public constructor(source: string) {
28 if (!source)
29 throw new Error(
30 "Class of type Loader was initialized without the *required* source parameter.",
31 );
32
33 this.source = source;
34 }
35
36 /**
37 * Recursively collects data from a directory based on the path specificed in dataSource property.
38 */
39 public async collect() {
40 const glob = new Glob(`**/**.ts`);
41 const iterator = glob.scan(this.source);
42
43 try {
44 for await (const path of iterator) {
45 let moduleDefault: T | null;
46
47 try {
48 const module = await import(`${this.source}/${path}`);
49 moduleDefault = module.default;
50
51 if (!moduleDefault) continue;
52 } catch {
53 continue;
54 }
55
56 const final = await this.validate(moduleDefault);
57 if (!final) continue;
58
59 this.cache.push(final);
60 }
61 } catch {
62 console.error(`[Voidy] Specified loader target ${this.source} doesn't exist. Skipping...`);
63 return this;
64 }
65
66 return this;
67 }
68
69 /**
70 * Validates a singular element during data collection, and returns whatever should be written to the cache.
71 */
72 public abstract validate(data: Partial<T>): Promise<T | null>;
73
74 /**
75 * Returns the JSON-ified contents of the loader cache
76 */
77 public getJSON() {
78 return this.cache;
79 }
80}