diff --git a/package-lock.json b/package-lock.json
index 1a5352ac..1bdc5d2f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
+ "name": "discord-server-opensource",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
@@ -12,12 +13,15 @@
"@types/node-fetch": "^2.5.7",
"express": "^4.17.1",
"express-cache-middleware": "^1.0.1",
+ "faker": "^5.1.0",
"lambert-db": "^1.0.3",
+ "lambert-server": "^1.0.3",
"missing-native-js-functions": "^1.0.8",
"node-fetch": "^2.6.1",
"rethinkdb-ts": "^2.4.5"
},
"devDependencies": {
+ "@types/faker": "^5.1.5",
"@types/node": "^14.14.10",
"typescript": "^4.1.2"
}
@@ -68,6 +72,12 @@
"@types/range-parser": "*"
}
},
+ "node_modules/@types/faker": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.5.tgz",
+ "integrity": "sha512-2uEQFb7bsx68rqD4F8q95wZq6LTLOyexjv6BnvJogCO4jStkyc6IDEkODPQcWfovI6g6M3uPQ2/uD/oedJKkNw==",
+ "dev": true
+ },
"node_modules/@types/mime": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
@@ -498,6 +508,14 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/express-async-errors": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz",
+ "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==",
+ "peerDependencies": {
+ "express": "^4.16.2"
+ }
+ },
"node_modules/express-cache-middleware": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/express-cache-middleware/-/express-cache-middleware-1.0.1.tgz",
@@ -514,6 +532,11 @@
"resolved": "git+ssh://git@github.com/tprobinson/express-mung.git#64ebd60cc4b5814ac05ea640dfd230c8df6f3527",
"license": "MIT"
},
+ "node_modules/faker": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/faker/-/faker-5.1.0.tgz",
+ "integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw=="
+ },
"node_modules/fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
@@ -766,6 +789,16 @@
"mongoose": "^5.11.8"
}
},
+ "node_modules/lambert-server": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.0.3.tgz",
+ "integrity": "sha512-nPYnj+Rrzwa8JY7NW4vaEJYZFJ3QMTxNIVUOb2RZP/mwrTzuNhsSe0p/qRx1FS+oAO7lx4T+PWoJeKtdQaDeUg==",
+ "dependencies": {
+ "express": "^4.17.1",
+ "express-async-errors": "^3.1.1",
+ "missing-native-js-functions": "^1.0.9"
+ }
+ },
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -903,9 +936,9 @@
}
},
"node_modules/missing-native-js-functions": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.8.tgz",
- "integrity": "sha512-nz3elX9mm8d0Pk/dLwqj148mCP3Al6hufbWhKQ9GHxo8xAVFA3+Q1NzcBkbVeu4gBrlsk7Rd6nTuxNiX47+pXA=="
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.9.tgz",
+ "integrity": "sha512-1xaJlMy7hZ27uwbgXr8bPmcVw5JZMPxdzRBGYKBD9QEaNiWiVsBmauBBrThSvV50iCb+x6yGGqAYihKahSitcA=="
},
"node_modules/mkdirp": {
"version": "1.0.4",
@@ -1732,6 +1765,12 @@
"@types/range-parser": "*"
}
},
+ "@types/faker": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.1.5.tgz",
+ "integrity": "sha512-2uEQFb7bsx68rqD4F8q95wZq6LTLOyexjv6BnvJogCO4jStkyc6IDEkODPQcWfovI6g6M3uPQ2/uD/oedJKkNw==",
+ "dev": true
+ },
"@types/mime": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
@@ -2071,6 +2110,12 @@
"vary": "~1.1.2"
}
},
+ "express-async-errors": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz",
+ "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==",
+ "requires": {}
+ },
"express-cache-middleware": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/express-cache-middleware/-/express-cache-middleware-1.0.1.tgz",
@@ -2083,6 +2128,11 @@
"version": "git+ssh://git@github.com/tprobinson/express-mung.git#64ebd60cc4b5814ac05ea640dfd230c8df6f3527",
"from": "express-mung@git+https://github.com/tprobinson/express-mung.git#sendFork"
},
+ "faker": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/faker/-/faker-5.1.0.tgz",
+ "integrity": "sha512-RrWKFSSA/aNLP0g3o2WW1Zez7/MnMr7xkiZmoCfAGZmdkDQZ6l2KtuXHN5XjdvpRjDl8+3vf+Rrtl06Z352+Mw=="
+ },
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
@@ -2270,6 +2320,16 @@
"mongoose": "^5.11.8"
}
},
+ "lambert-server": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.0.3.tgz",
+ "integrity": "sha512-nPYnj+Rrzwa8JY7NW4vaEJYZFJ3QMTxNIVUOb2RZP/mwrTzuNhsSe0p/qRx1FS+oAO7lx4T+PWoJeKtdQaDeUg==",
+ "requires": {
+ "express": "^4.17.1",
+ "express-async-errors": "^3.1.1",
+ "missing-native-js-functions": "^1.0.9"
+ }
+ },
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -2370,9 +2430,9 @@
}
},
"missing-native-js-functions": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.8.tgz",
- "integrity": "sha512-nz3elX9mm8d0Pk/dLwqj148mCP3Al6hufbWhKQ9GHxo8xAVFA3+Q1NzcBkbVeu4gBrlsk7Rd6nTuxNiX47+pXA=="
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.0.9.tgz",
+ "integrity": "sha512-1xaJlMy7hZ27uwbgXr8bPmcVw5JZMPxdzRBGYKBD9QEaNiWiVsBmauBBrThSvV50iCb+x6yGGqAYihKahSitcA=="
},
"mkdirp": {
"version": "1.0.4",
diff --git a/package.json b/package.json
index ab7e5414..ba744d28 100644
--- a/package.json
+++ b/package.json
@@ -22,12 +22,15 @@
"@types/node-fetch": "^2.5.7",
"express": "^4.17.1",
"express-cache-middleware": "^1.0.1",
+ "faker": "^5.1.0",
"lambert-db": "^1.0.3",
+ "lambert-server": "^1.0.3",
"missing-native-js-functions": "^1.0.8",
"node-fetch": "^2.6.1",
"rethinkdb-ts": "^2.4.5"
},
"devDependencies": {
+ "@types/faker": "^5.1.5",
"@types/node": "^14.14.10",
"typescript": "^4.1.2"
}
diff --git a/src/Server.ts b/src/Server.ts
index 92c73a35..39b1fa56 100644
--- a/src/Server.ts
+++ b/src/Server.ts
@@ -2,27 +2,26 @@ import express, { Application, Router } from "express";
import { traverseDirectory } from "./Utils";
import { Server as HTTPServer } from "http";
import fs from "fs/promises";
+import { Server, ServerOptions } from "lambert-server";
-export type ServerOptions = {
- port: number;
-};
+export interface DiscordServerOptions extends ServerOptions {}
-export class Server {
- private app: Application;
- private http: HTTPServer;
- private options: ServerOptions;
- private routes: Router[];
- private initalized: Promise<any>;
-
- constructor(opts: ServerOptions = { port: 8080 }) {
- this.options = opts;
+declare global {
+ namespace Express {
+ interface Request {
+ server: DiscordServer;
+ }
+ }
+}
- this.app = express();
+export class DiscordServer extends Server {
+ public options: DiscordServerOptions;
- this.initalized = this.init();
+ constructor(opts?: DiscordServerOptions) {
+ super(opts);
}
- async init() {
+ async start() {
// recursively loads files in routes/
this.routes = await this.registerRoutes(__dirname + "/routes/");
// const indexHTML = await (await fetch("https://discord.com/app")).buffer();
@@ -33,39 +32,6 @@ export class Server {
res.set("content-type", "text/html");
res.send(indexHTML);
});
- }
-
- async start() {
- await this.initalized;
- await new Promise<void>((res) => this.app.listen(this.options.port, () => res()));
- console.log(`[Server] started on ${this.options.port}`);
- }
-
- async registerRoutes(root: string) {
- return await traverseDirectory({ dirname: root, recursive: true }, this.registerRoute.bind(this, root));
- }
-
- registerRoute(root: string, file: string): any {
- if (root.endsWith("/") || root.endsWith("\\")) root = root.slice(0, -1); // removes slash at the end of the root dir
- let path = file.replace(root, ""); // remove root from path and
- path = path.split(".").slice(0, -1).join("."); // trancate .js/.ts file extension of path
- if (path.endsWith("/index")) path = path.slice(0, -6); // delete index from path
-
- try {
- var router = require(file);
- if (router.router) router = router.router;
- if (router.default) router = router.default;
- if (!router || router?.prototype?.constructor?.name !== "router")
- throw `File doesn't export any default router`;
- this.app.use(path, <Router>router);
- console.log(`[Server] Route ${path} registerd`);
- return router;
- } catch (error) {
- console.error(new Error(`[Server] Failed to register route ${path}: ${error}`));
- }
- }
-
- async stop() {
- return new Promise<void>((res) => this.http.close(() => res()));
+ return super.start();
}
}
diff --git a/src/index.ts b/src/index.ts
index 8765d6dc..2f8aa185 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,4 @@
-import { Server } from "./Server";
+import { DiscordServer } from "./Server";
-const server = new Server();
+const server = new DiscordServer();
server.start().catch(console.error);
diff --git a/src/models/Guild.ts.disabled b/src/models/Guild.ts.disabled
new file mode 100644
index 00000000..5cffa9b8
--- /dev/null
+++ b/src/models/Guild.ts.disabled
@@ -0,0 +1,59 @@
+import { Snowflake } from "./Snowflake";
+
+export interface Guild {
+ afkChannel?: Snowflake;
+ afkTimeout: number;
+ onlineCount: number;
+ available: boolean;
+ banner: string | null;
+ channels: GuildChannelManager;
+ readonly createdTimestamp: number;
+ defaultMessageNotifications: DefaultMessageNotifications | number;
+ deleted: boolean;
+ description: string | null;
+ discoverySplash: string | null;
+ embedChannel: GuildChannel | null;
+ embedChannelID: Snowflake | null;
+ embedEnabled: boolean;
+ emojis: GuildEmojiManager;
+ explicitContentFilter: ExplicitContentFilterLevel;
+ features: GuildFeatures[];
+ icon: string | null;
+ id: Snowflake;
+ joinedTimestamp: number;
+ large: boolean;
+ maximumMembers: number | null;
+ maximumPresences: number | null;
+ memberCount: number;
+ members: GuildMemberManager;
+ mfaLevel: number;
+ name: string;
+ readonly nameAcronym: string;
+ readonly owner: Snowflake | null;
+ ownerID: Snowflake;
+ readonly partnered: boolean;
+ preferredLocale: string;
+ premiumSubscriptionCount: number | null;
+ premiumTier: PremiumTier;
+ presences: PresenceManager;
+ readonly publicUpdatesChannel: TextChannel | null;
+ publicUpdatesChannelID: Snowflake | null;
+ region: string;
+ roles: RoleManager;
+ readonly rulesChannel: TextChannel | null;
+ rulesChannelID: Snowflake | null;
+ readonly shard: WebSocketShard;
+ shardID: number;
+ splash: string | null;
+ readonly systemChannel: TextChannel | null;
+ systemChannelFlags: Readonly<SystemChannelFlags>;
+ systemChannelID: Snowflake | null;
+ vanityURLCode: string | null;
+ vanityURLUses: number | null;
+ verificationLevel: VerificationLevel;
+ readonly verified: boolean;
+ readonly voiceStates: VoiceStateManager;
+ readonly widgetChannel: TextChannel | null;
+ widgetChannelID: Snowflake | null;
+ widgetEnabled: boolean | null;
+}
diff --git a/src/models/Snowflake.ts b/src/models/Snowflake.ts
new file mode 100644
index 00000000..02e6df3a
--- /dev/null
+++ b/src/models/Snowflake.ts
@@ -0,0 +1 @@
+export type Snowflake = string;
diff --git a/src/models/database.ts b/src/models/database.ts
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/models/database.ts
diff --git a/src/routes/api/v8/channel/#CHANNELID/index.ts b/src/routes/api/v8/channel/#CHANNELID/index.ts
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/routes/api/v8/channel/#CHANNELID/index.ts
diff --git a/src/routes/api/v8/guilds/index.ts b/src/routes/api/v8/guilds/index.ts
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/routes/api/v8/guilds/index.ts
diff --git a/src/test.ts b/src/test.ts
deleted file mode 100644
index 8dc237d9..00000000
--- a/src/test.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { r } from "rethinkdb-ts";
-
-async function main() {
- await r.connectPool();
-
- const result = await r.db("test").tableCreate("authors").run();
- console.log(result);
-}
-
-main();
diff --git a/src/test/db_benchmark.ts b/src/test/db_benchmark.ts
new file mode 100644
index 00000000..74623e06
--- /dev/null
+++ b/src/test/db_benchmark.ts
@@ -0,0 +1,55 @@
+// @ts-nocheck
+import { r } from "rethinkdb-ts";
+import faker from "faker";
+import cluster from "cluster";
+import { performance } from "perf_hooks";
+
+console.log("starting");
+
+if (cluster.isMaster) {
+ for (var i = 0; i < 1; i++) {
+ cluster.fork();
+ }
+ console.log("all nodes started");
+}
+
+if (cluster.isWorker) {
+ const inserts = [];
+
+ for (let i = 0; i < 100; i++) {
+ inserts.push({
+ color: faker.commerce.color(),
+ department: faker.commerce.department(),
+ price: faker.commerce.price(),
+ product: faker.commerce.product(),
+ productAdjective: faker.commerce.productAdjective(),
+ productName: faker.commerce.productName(),
+ productMaterial: faker.commerce.productMaterial(),
+ productDescription: faker.commerce.productDescription(),
+ });
+ }
+
+ async function main(connection) {
+ const start = performance.now();
+ await r
+ .db("test")
+ .table("test")
+ .nth(Math.floor(Math.random() * 300000))
+ .run(connection);
+ const end = performance.now();
+ // console.log(end - start);
+
+ // await main(connection);
+ setTimeout(main.bind(null, connection));
+ }
+
+ (async () => {
+ const threads = 30;
+
+ for (var i = 0; i < threads; i++) {
+ setTimeout(async () => {
+ main(await r.connect({ port: 28015, host: "192.168.178.122" }));
+ });
+ }
+ })();
+}
|