feat: simple plugin natives (#1965)

This commit is contained in:
V 2023-11-09 02:32:34 +01:00 committed by GitHub
parent 32f2043193
commit 119b628f33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 200 additions and 80 deletions

View file

@ -18,8 +18,10 @@
*/
import esbuild from "esbuild";
import { readdir } from "fs/promises";
import { join } from "path";
import { BUILD_TIMESTAMP, commonOpts, globPlugins, isStandalone, updaterDisabled, VERSION, watch } from "./common.mjs";
import { BUILD_TIMESTAMP, commonOpts, existsAsync, globPlugins, isStandalone, updaterDisabled, VERSION, watch } from "./common.mjs";
const defines = {
IS_STANDALONE: isStandalone,
@ -43,13 +45,59 @@ const nodeCommonOpts = {
format: "cjs",
platform: "node",
target: ["esnext"],
external: ["electron", "original-fs", ...commonOpts.external],
external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external],
define: defines,
};
const sourceMapFooter = s => watch ? "" : `//# sourceMappingURL=vencord://${s}.js.map`;
const sourcemap = watch ? "inline" : "external";
/**
* @type {import("esbuild").Plugin}
*/
const globNativesPlugin = {
name: "glob-natives-plugin",
setup: build => {
const filter = /^~pluginNatives$/;
build.onResolve({ filter }, args => {
return {
namespace: "import-natives",
path: args.path
};
});
build.onLoad({ filter, namespace: "import-natives" }, async () => {
const pluginDirs = ["plugins", "userplugins"];
let code = "";
let natives = "\n";
let i = 0;
for (const dir of pluginDirs) {
const dirPath = join("src", dir);
if (!await existsAsync(dirPath)) continue;
const plugins = await readdir(dirPath);
for (const p of plugins) {
if (!await existsAsync(join(dirPath, p, "native.ts"))) continue;
const nameParts = p.split(".");
const namePartsWithoutTarget = nameParts.length === 1 ? nameParts : nameParts.slice(0, -1);
// pluginName.thing.desktop -> PluginName.thing
const cleanPluginName = p[0].toUpperCase() + namePartsWithoutTarget.join(".").slice(1);
const mod = `p${i}`;
code += `import * as ${mod} from "./${dir}/${p}/native";\n`;
natives += `${JSON.stringify(cleanPluginName)}:${mod},\n`;
i++;
}
}
code += `export default {${natives}};`;
return {
contents: code,
resolveDir: "./src"
};
});
}
};
await Promise.all([
// Discord Desktop main & renderer & preload
esbuild.build({
@ -62,7 +110,11 @@ await Promise.all([
...defines,
IS_DISCORD_DESKTOP: true,
IS_VESKTOP: false
}
},
plugins: [
...nodeCommonOpts.plugins,
globNativesPlugin
]
}),
esbuild.build({
...commonOpts,
@ -107,7 +159,11 @@ await Promise.all([
...defines,
IS_DISCORD_DESKTOP: false,
IS_VESKTOP: true
}
},
plugins: [
...nodeCommonOpts.plugins,
globNativesPlugin
]
}),
esbuild.build({
...commonOpts,

View file

@ -20,8 +20,8 @@ import "../suppressExperimentalWarnings.js";
import "../checkNodeVersion.js";
import { exec, execSync } from "child_process";
import { existsSync, readFileSync } from "fs";
import { readdir, readFile } from "fs/promises";
import { constants as FsConstants, readFileSync } from "fs";
import { access, readdir, readFile } from "fs/promises";
import { join, relative } from "path";
import { promisify } from "util";
@ -47,6 +47,12 @@ export const banner = {
const isWeb = process.argv.slice(0, 2).some(f => f.endsWith("buildWeb.mjs"));
export function existsAsync(path) {
return access(path, FsConstants.F_OK)
.then(() => true)
.catch(() => false);
}
// https://github.com/evanw/esbuild/issues/619#issuecomment-751995294
/**
* @type {import("esbuild").Plugin}
@ -79,7 +85,7 @@ export const globPlugins = kind => ({
let plugins = "\n";
let i = 0;
for (const dir of pluginDirs) {
if (!existsSync(`./src/${dir}`)) continue;
if (!await existsAsync(`./src/${dir}`)) continue;
const files = await readdir(`./src/${dir}`);
for (const file of files) {
if (file.startsWith("_") || file.startsWith(".")) continue;