From 7f3dd6ef87adfc7fab924e0bf294e09e6a07ef44 Mon Sep 17 00:00:00 2001
From: thororen1234 <78185467+thororen1234@users.noreply.github.com>
Date: Sat, 30 Aug 2025 22:56:41 -0400
Subject: [PATCH] Add Dev List
---
.github/workflows/build.yml | 1 +
.github/workflows/nixosBuild.yml | 1 +
package.json | 1 +
scripts/generateDevsList.ts | 131 +++++++++++++++++++++++++++++++
4 files changed, 134 insertions(+)
create mode 100644 scripts/generateDevsList.ts
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 77250b9d3..2050ad109 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -42,6 +42,7 @@ jobs:
pnpm generatePluginJson dist/plugins.json
pnpm generateEquicordPluginJson dist/equicordplugins.json
pnpm generateVencordPluginJson dist/vencordplugins.json
+ pnpm generateDevsList dist/devs.json
- name: Collect files to be released
run: |
diff --git a/.github/workflows/nixosBuild.yml b/.github/workflows/nixosBuild.yml
index 6890f7748..50d7638ff 100644
--- a/.github/workflows/nixosBuild.yml
+++ b/.github/workflows/nixosBuild.yml
@@ -39,6 +39,7 @@ jobs:
pnpm generatePluginJson dist/plugins.json
pnpm generateEquicordPluginJson dist/equicordplugins.json
pnpm generateVencordPluginJson dist/vencordplugins.json
+ pnpm generateDevsList dist/devs.json
- name: Collect files to be released
run: |
diff --git a/package.json b/package.json
index cf0a7f373..c62a68020 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"watch": "pnpm build --watch",
"dev": "pnpm watch",
"watchWeb": "pnpm buildWeb --watch",
+ "generateDevsList": "tsx scripts/generateDevsList.ts",
"generatePluginJson": "tsx scripts/generatePluginList.ts",
"generateEquicordPluginJson": "tsx scripts/generateEquicordPluginList.ts",
"generateVencordPluginJson": "tsx scripts/generateVencordPluginList.ts",
diff --git a/scripts/generateDevsList.ts b/scripts/generateDevsList.ts
new file mode 100644
index 000000000..472358728
--- /dev/null
+++ b/scripts/generateDevsList.ts
@@ -0,0 +1,131 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2023 Vendicated and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+import { Dirent, readdirSync, readFileSync, writeFileSync } from "fs";
+import { access, readFile } from "fs/promises";
+import { join, sep } from "path";
+import { normalize as posixNormalize, sep as posixSep } from "path/posix";
+import { BigIntLiteral, createSourceFile, Identifier, isArrayLiteralExpression, isCallExpression, isExportAssignment, isIdentifier, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, isSatisfiesExpression, isStringLiteral, isVariableStatement, NamedDeclaration, NodeArray, ObjectLiteralExpression, PropertyAssignment, ScriptTarget, StringLiteral, SyntaxKind } from "typescript";
+
+import { getPluginTarget } from "./utils.mjs";
+
+interface Dev {
+ name: string;
+ id: string;
+}
+
+interface Command {
+ name: string;
+ description: string;
+}
+
+const devs = {} as Record;
+const equicordDevs = {} as Record;
+
+function getName(node: NamedDeclaration) {
+ return node.name && isIdentifier(node.name) ? node.name.text : undefined;
+}
+
+function hasName(node: NamedDeclaration, name: string) {
+ return getName(node) === name;
+}
+
+function getObjectProp(node: ObjectLiteralExpression, name: string) {
+ const prop = node.properties.find(p => hasName(p, name));
+ if (prop && isPropertyAssignment(prop)) return prop.initializer;
+ return prop;
+}
+
+function parseDevs() {
+ const file = createSourceFile("constants.ts", readFileSync("src/utils/constants.ts", "utf8"), ScriptTarget.Latest);
+
+ for (const child of file.getChildAt(0).getChildren()) {
+ if (!isVariableStatement(child)) continue;
+
+ const devsDeclaration = child.declarationList.declarations.find(d => hasName(d, "Devs"));
+ if (!devsDeclaration?.initializer || !isCallExpression(devsDeclaration.initializer)) continue;
+
+ const value = devsDeclaration.initializer.arguments[0];
+
+ if (!isSatisfiesExpression(value) || !isObjectLiteralExpression(value.expression)) throw new Error("Failed to parse devs: not an object literal");
+
+ for (const prop of value.expression.properties) {
+ const name = (prop.name as Identifier).text;
+ const value = isPropertyAssignment(prop) ? prop.initializer : prop;
+
+ if (!isObjectLiteralExpression(value)) throw new Error(`Failed to parse devs: ${name} is not an object literal`);
+
+ devs[name] = {
+ name: (getObjectProp(value, "name") as StringLiteral).text,
+ id: (getObjectProp(value, "id") as BigIntLiteral).text.slice(0, -1)
+ };
+ }
+
+ return;
+ }
+
+ throw new Error("Could not find Devs constant");
+}
+
+function parseEquicordDevs() {
+ const file = createSourceFile("constants.ts", readFileSync("src/utils/constants.ts", "utf8"), ScriptTarget.Latest);
+
+ for (const child of file.getChildAt(0).getChildren()) {
+ if (!isVariableStatement(child)) continue;
+
+ const devsDeclaration = child.declarationList.declarations.find(d => hasName(d, "EquicordDevs"));
+ if (!devsDeclaration?.initializer || !isCallExpression(devsDeclaration.initializer)) continue;
+
+ const value = devsDeclaration.initializer.arguments[0];
+
+ if (!isSatisfiesExpression(value) || !isObjectLiteralExpression(value.expression)) throw new Error("Failed to parse EquicordDevs: not an object literal");
+
+ for (const prop of value.expression.properties) {
+ const name = (prop.name as Identifier).text;
+ const value = isPropertyAssignment(prop) ? prop.initializer : prop;
+
+ if (!isObjectLiteralExpression(value)) throw new Error(`Failed to parse EquicordDevs: ${name} is not an object literal`);
+
+ equicordDevs[name] = {
+ name: (getObjectProp(value, "name") as StringLiteral).text,
+ id: (getObjectProp(value, "id") as BigIntLiteral).text.slice(0, -1)
+ };
+ }
+
+ return;
+ }
+
+ throw new Error("Could not find EquicordDevs constant");
+}
+
+(async () => {
+ parseDevs();
+ parseEquicordDevs();
+
+ const allDevs = {
+ equicord: equicordDevs,
+ vencord: devs
+ };
+
+ const data = JSON.stringify(allDevs, null, 2);
+ if (process.argv.length > 2) {
+ writeFileSync(process.argv[2], data);
+ } else {
+ console.log(data);
+ }
+})();