forked from Ittai/ittai
parent
7f448d0910
commit
47868b22f5
|
@ -1,6 +1,5 @@
|
|||
<p align="center">
|
||||
<img src="./assets/png/dark/Background.png" width="2000">
|
||||
<sup>Logo made by Sylix#8103 (267131905688862720)</sup>
|
||||
<img src="./assets/png/dark/Background.png" alt="Ittai Logo made by Sylix#8103" width="2000">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
@ -22,7 +21,7 @@
|
|||
## Features
|
||||
|
||||
- Build even single-file BD plugins from multi-file projects.
|
||||
- Write one codebase, distribute one product.
|
||||
- Write one codebase, run it anywhere.
|
||||
- Hot rebuild your plugins.
|
||||
- Use various flavors of JS to create your plugins.
|
||||
- [x] [JSX and TSX support](https://reactjs.org/docs/introducing-jsx.html)
|
||||
|
@ -98,5 +97,5 @@ pnpm link --global ittai
|
|||
This command will build your plugin for BetterDiscord, Powercord v2, and GooseMod, but will only copy it to BetterDiscord's plugins folder. It will also hot rebuild your plugin for you.
|
||||
|
||||
```bash
|
||||
ittai --plugin="./test/plugin" --betterdiscord="/path/to/plugins/fgbd" --powercordv2 --goosemod --watch
|
||||
ittai --plugin="./test/plugin" --betterdiscord="/path/to/plugins/fgbd" --powercordv2="/path/to/plugins/fgbd" --goosemod-"/path/to/plugins/fgbd" --watch
|
||||
```
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"sourceMaps": true
|
||||
}
|
|
@ -1,68 +1,34 @@
|
|||
const yargs = require("yargs/yargs");
|
||||
const { hideBin } = require("yargs/helpers");
|
||||
const { argv } = yargs(hideBin(process.argv));
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
const ExtraWatchWebpackPlugin = require("extra-watch-webpack-plugin");
|
||||
// const beautify = require("js-beautify").js;
|
||||
const rollup = require("rollup");
|
||||
const commonjs = require("@rollup/plugin-commonjs");
|
||||
const styles = require("rollup-plugin-styles");
|
||||
const json = require("@rollup/plugin-json");
|
||||
const { nodeResolve } = require("@rollup/plugin-node-resolve");
|
||||
const { default: esbuild } = require("rollup-plugin-esbuild");
|
||||
const alias = require("@rollup/plugin-alias");
|
||||
const replace = require("@rollup/plugin-replace");
|
||||
const memfs = require("rollup-plugin-memory-fs");
|
||||
const isValidPath = require("is-valid-path");
|
||||
const term = require("terminal-kit").terminal;
|
||||
|
||||
const { defaultIttaiSettings, ittaiSettings, ittaiSettingsPath } = require("../utils/settings");
|
||||
const appliedSettings = Object.assign({}, defaultIttaiSettings, ittaiSettings)
|
||||
const DevServer = require("../devserver");
|
||||
const logger = require("../utils/logger")
|
||||
const logger = require("../utils/logger");
|
||||
const progress = require("./plugins/progress");
|
||||
const appliedSettings = Object.assign({}, defaultIttaiSettings, ittaiSettings)
|
||||
|
||||
let core;
|
||||
|
||||
function nanoseconds() {
|
||||
const hrTime = process.hrtime();
|
||||
return hrTime[0] * 1000000000 + hrTime[1];
|
||||
function sleep(ms) {
|
||||
return new Promise(r => setTimeout(r, ms))
|
||||
}
|
||||
|
||||
// const { header } = require("../ui");
|
||||
|
||||
let startTime;
|
||||
let error = false;
|
||||
let _argv;
|
||||
let ds;
|
||||
let hasCreatedOutputPath;
|
||||
|
||||
let dist = "";
|
||||
|
||||
let fsMap = new Map();
|
||||
const mockFs = /*new Proxy(*/{
|
||||
mkdir: (p, cb) => {
|
||||
// console.log(path)
|
||||
if (p === "/ittaiTemp") {
|
||||
hasCreatedOutputPath = true;
|
||||
cb();
|
||||
}
|
||||
},
|
||||
join: path.join,
|
||||
stat: (p, cb) => {
|
||||
// if (p === "/ittaiTemp/index.js") {
|
||||
cb(true);
|
||||
// }
|
||||
},
|
||||
writeFile: (p, buf, cb) => {
|
||||
fsMap.set(p.replace(/\\/g, "/").replace(/^\/ittaiTemp\//, ""), buf);
|
||||
cb();
|
||||
}
|
||||
}/*, {
|
||||
get: (t, p, r) => {
|
||||
console.log("getting func " + p);
|
||||
return (...args) => {
|
||||
console.log("args of func " + p, args);
|
||||
if (t[p]) {
|
||||
return t[p](...args);
|
||||
}
|
||||
}
|
||||
}
|
||||
})*/
|
||||
let watcher;
|
||||
|
||||
process.on("SIGINT", () => {
|
||||
term("\n\n")
|
||||
|
@ -70,13 +36,12 @@ process.on("SIGINT", () => {
|
|||
if (_argv.watch) {
|
||||
ds.stop();
|
||||
}
|
||||
// try {
|
||||
// fs.rmSync(dist, { recursive: true });
|
||||
// } catch (e) {}
|
||||
watcher.close();
|
||||
term.hideCursor(false);
|
||||
term.processExit(130); //130 means "Script terminated by Control-C" for Bash
|
||||
})
|
||||
|
||||
function build(argv, forceNoWatch = false) {
|
||||
async function build(argv, forceNoWatch = false) {
|
||||
const pluginPath = argv.plugin ?? argv.p ?? process.cwd()
|
||||
|
||||
const manifest = ittaiSettings?.manifest
|
||||
|
@ -87,527 +52,179 @@ function build(argv, forceNoWatch = false) {
|
|||
|
||||
_argv = argv;
|
||||
core = path.resolve(pluginPath, "node_modules", "ittai");
|
||||
return new Promise((resolve) => {
|
||||
if (
|
||||
manifest != null &&
|
||||
fs.existsSync(pluginPath) &&
|
||||
fs.existsSync(ittaiSettingsPath) &&
|
||||
fs.existsSync(core)
|
||||
) {
|
||||
dist = argv.output ?? ittaiSettings.output ?? path.resolve(path.join(pluginPath, "..", pluginName + "-dist"));
|
||||
fs.ensureDirSync(dist)
|
||||
let mods = [];
|
||||
for (let mod of ["betterdiscord", "powercordv2", "goosemod"]) {
|
||||
if (argv[mod]) mods.push(mod);
|
||||
}
|
||||
if (argv.watch && mods.length >> 1) {
|
||||
term.red("You can only build for one mod at a time in watch mode.\n");
|
||||
process.exit(1);
|
||||
}
|
||||
let promises = [];
|
||||
for (let mod of mods) {
|
||||
promises.push(new Promise((resolve) => {
|
||||
if (
|
||||
manifest != null &&
|
||||
fs.existsSync(pluginPath) &&
|
||||
fs.existsSync(ittaiSettingsPath) &&
|
||||
fs.existsSync(core)
|
||||
) {
|
||||
const localFormat = Boolean(appliedSettings.customClassNames)
|
||||
? (
|
||||
typeof appliedSettings.customClassNames === "string" ?
|
||||
appliedSettings.customClassNames.replace("[plugin]", pluginName.replace(/ /g, "")) :
|
||||
defaultIttaiSettings.customClassNames.replace("[plugin]", pluginName.replace(/ /g, ""))
|
||||
)
|
||||
: "[local]"
|
||||
|
||||
|
||||
|
||||
// term.eraseDisplay();
|
||||
// header(argv);
|
||||
|
||||
// fs.ensureFileSync(path.join(dist, "index.js"));
|
||||
// fs.ensureFileSync(path.join(dist, "manifest.json"));
|
||||
|
||||
// const stylesheetLoader = path.resolve(
|
||||
// path.join(__dirname, "stylesheetLoader.js")
|
||||
// );
|
||||
const styleLoader = {
|
||||
loader: require.resolve("style-loader"),
|
||||
options: {
|
||||
attributes: { ittai: true, plugin: pluginName }
|
||||
if (argv.watch) {
|
||||
ds = new DevServer(pluginName);
|
||||
ds.start();
|
||||
term.fullscreen(false);
|
||||
term.moveTo(1, 1);
|
||||
// term.hideCursor()
|
||||
}
|
||||
};
|
||||
const localFormat = Boolean(appliedSettings.customClassNames)
|
||||
? (
|
||||
typeof appliedSettings.customClassNames === "string" ?
|
||||
appliedSettings.customClassNames.replace("[plugin]", pluginName.replace(/ /g, "")) :
|
||||
defaultIttaiSettings.customClassNames.replace("[plugin]", pluginName.replace(/ /g, ""))
|
||||
)
|
||||
: "[local]"
|
||||
|
||||
// const jsBuilder = {
|
||||
// loader: require.resolve("@sucrase/webpack-loader"),
|
||||
// options: {
|
||||
// production: argv.production ? true : false,
|
||||
// // enableLegacyBabel5ModuleInterop: true,
|
||||
// transforms: ["jsx", "imports"],
|
||||
// }
|
||||
// };
|
||||
|
||||
const jsBuilder = {
|
||||
loader: require.resolve("swc-loader"),
|
||||
options: {
|
||||
jsc: {
|
||||
target: "es2021",
|
||||
parser: {
|
||||
syntax: "ecmascript",
|
||||
jsx: true,
|
||||
dynamicImport: false,
|
||||
privateMethod: false,
|
||||
functionBind: false,
|
||||
classPrivateProperty: false,
|
||||
exportDefaultFrom: false,
|
||||
exportNamespaceFrom: false,
|
||||
decorators: false,
|
||||
decoratorsBeforeExport: false,
|
||||
importMeta: false,
|
||||
topLevelAwait: true
|
||||
},
|
||||
transform: {
|
||||
react: {
|
||||
runtime: "classic"
|
||||
}
|
||||
}
|
||||
}
|
||||
const env = {
|
||||
preventAssignment: true,
|
||||
"process.env.NODE_ENV": argv.production ? '"production"' : '"development"',
|
||||
"process.env.CLIENT_MOD": JSON.stringify(mod),
|
||||
"process.env.DEV_MODE": mod !== "betterdiscord" && !argv.production ? '"true"' : '"false"',
|
||||
"process.env.HAS_CHANGELOG": manifest.changelog ? '"true"' : '"false"'
|
||||
}
|
||||
}
|
||||
const tsBuilder = {
|
||||
loader: require.resolve("swc-loader"),
|
||||
options: {
|
||||
jsc: {
|
||||
target: "es2021",
|
||||
parser: {
|
||||
syntax: "typescript",
|
||||
tsx: true,
|
||||
dynamicImport: false,
|
||||
decorators: false,
|
||||
topLevelAwait: true
|
||||
},
|
||||
transform: {
|
||||
react: {
|
||||
runtime: "classic"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argv.watch) {
|
||||
ds = new DevServer(pluginName);
|
||||
ds.start();
|
||||
term.fullscreen(false);
|
||||
term.moveTo(1, 1);
|
||||
// term.hideCursor()
|
||||
}
|
||||
|
||||
const progressBar = term.progressBar({
|
||||
width: Math.round(term.width / 1.5),
|
||||
title: ` ITTAI ^`,
|
||||
titleStyle: term.bold.white[["bgBrightRed", "bgBrightGreen", "bgCyan", "bgBrightMagenta", "bgYellow"][Math.floor(Math.random() * 5)]],
|
||||
eta: argv.production ?? false,
|
||||
percent: true,
|
||||
barStyle: term.green,
|
||||
percentStyle: term.green
|
||||
});
|
||||
|
||||
const compiler = webpack(
|
||||
{
|
||||
mode: argv.production ? "production" : "development",
|
||||
devtool: argv.production ? "source-map" : false,
|
||||
target: "browserslist:chrome 91",
|
||||
// publicPath: "/",
|
||||
|
||||
entry: path.resolve(pluginPath),
|
||||
context: path.resolve(pluginPath),
|
||||
output: {
|
||||
library: "plugin",
|
||||
libraryTarget: "var",
|
||||
filename: "index.js",
|
||||
path: "/ittaiTemp",
|
||||
devtoolModuleFilenameTemplate: info =>
|
||||
`file:///${pluginName}/${info.resourcePath}`.replace(
|
||||
/\\/g,
|
||||
'/',
|
||||
) // windows moment
|
||||
// `file:///${path.resolve(info.absoluteResourcePath).replace(
|
||||
// /\\/g,
|
||||
// '/',
|
||||
// )}`,
|
||||
},
|
||||
experiments: {
|
||||
topLevelAwait: false
|
||||
/**
|
||||
* @type {import("rollup").RollupOptions}
|
||||
*/
|
||||
const rollupConfig = {
|
||||
input: path.join(core, "loader", "entrypoint.ts"),
|
||||
watch: {
|
||||
skipWrite: true
|
||||
},
|
||||
plugins: [
|
||||
new ExtraWatchWebpackPlugin({
|
||||
dirs: [core],
|
||||
}),
|
||||
new webpack.ProgressPlugin((percentage, message, ...args) => {
|
||||
if (percentage === 0) {
|
||||
startTime = nanoseconds();
|
||||
error = false;
|
||||
if (argv.watch) {
|
||||
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J"); // clears scrollback
|
||||
term.clear();
|
||||
term.moveTo(1, 1);
|
||||
}
|
||||
// term.eraseDisplay();
|
||||
// header(argv);
|
||||
}
|
||||
progressBar.update({
|
||||
progress: percentage,
|
||||
});
|
||||
if (percentage === 1) {
|
||||
term.eraseLine();
|
||||
|
||||
if (error) {
|
||||
errored = true;
|
||||
if (argv.watch) {
|
||||
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J"); // clears scrollback
|
||||
term.clear();
|
||||
term.moveTo(1, 1);
|
||||
}
|
||||
|
||||
if (error.err) {
|
||||
term.red((error.err.stack || error.err) + "\n");
|
||||
if (err.details) {
|
||||
term.red(error.err.details + "\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
const info = error.stats.toJson();
|
||||
if (error.stats.hasErrors()) {
|
||||
for (const error of info.errors)
|
||||
term.red(error.message + "\n");
|
||||
}
|
||||
if (error.stats.hasWarnings()) {
|
||||
for (const warning of info.warnings)
|
||||
term.red(warning.message + "\n");
|
||||
}
|
||||
logger.makeBadge("!", term.bold.bgRed)("Build failed after ")
|
||||
.red(`${Math.round((nanoseconds() - startTime) / 1000000).toLocaleString()} ms`)
|
||||
(".\n");
|
||||
// term.hideCursor();
|
||||
|
||||
// return resolve();
|
||||
} else {
|
||||
const localeOpts = { minimumIntegerDigits: 2, useGrouping: false }
|
||||
const currentTime = new Date()
|
||||
logger.makeBadge("✓", term.bold.bgGreen)
|
||||
("Build done! Built in ")
|
||||
.brightGreen(`${Math.round((nanoseconds() - startTime) / 1000000).toLocaleString()} ms`)
|
||||
(` at `)
|
||||
.cyan(`${currentTime.getHours().toLocaleString(undefined, localeOpts)}:${currentTime.getMinutes().toLocaleString(undefined, localeOpts)}:${currentTime.getSeconds().toLocaleString(undefined, localeOpts)}`)
|
||||
(".\n\n")
|
||||
}
|
||||
replace(env),
|
||||
alias({
|
||||
entries: {
|
||||
"@ittai/plugin": path.resolve(path.join(pluginPath, JSON.parse(fs.readFileSync(path.join(pluginPath, "package.json"), "utf-8")).main)),
|
||||
"@ittai/config": path.resolve(path.join(pluginPath, "ittaiconfig.json")),
|
||||
"react": path.resolve(path.join(core, "packages", "react.cjs")),
|
||||
"react-dom": path.resolve(path.join(core, "packages", "react-dom.cjs")),
|
||||
"react-spring": path.resolve(path.join(core, "packages", "react-spring.cjs")),
|
||||
"lodash": path.resolve(path.join(core, "packages", "lodash.cjs"))
|
||||
}
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
__ITTAI_WATCH__: !!argv.watch,
|
||||
__ITTAI_DEV__: !argv.production
|
||||
commonjs(),
|
||||
json(),
|
||||
styles({
|
||||
modules: {
|
||||
generateScopedName: localFormat
|
||||
},
|
||||
autoModules: true,
|
||||
}),
|
||||
new webpack.optimize.LimitChunkCountPlugin({
|
||||
maxChunks: 1, // TODO: figure out proper code splitting, this just disables it
|
||||
esbuild({
|
||||
target: "es2021",
|
||||
jsx: "transform",
|
||||
sourceMap: true
|
||||
}),
|
||||
new ForkTsCheckerWebpackPlugin({
|
||||
logger: {
|
||||
log: message => {
|
||||
if (~message.indexOf("No errors found.")) {
|
||||
term.getCursorLocation((err, x, y) => term
|
||||
.eraseLine().moveTo(1, y)
|
||||
.bold.bgBrightBlue(" TS ").brightBlue(` No issues found!`)
|
||||
)
|
||||
} else if (~message.indexOf("Type-checking in progress...")) {
|
||||
logger.makeBadge("TS", term.bold.bgGray).gray("Checking types...")
|
||||
} else term(message)
|
||||
},
|
||||
error: message => term.getCursorLocation((err, x, y) => term
|
||||
.eraseLine().moveTo(1, y)
|
||||
.bold.bgRed(" TS ").brightBlue(` ${message}`)
|
||||
)
|
||||
}
|
||||
})
|
||||
// new webpack.ProvidePlugin({
|
||||
// React: path.resolve(core, "libraries", "React.js"),
|
||||
// }),
|
||||
nodeResolve({
|
||||
extensions: [".ts", ".tsx", ".jsx", ".js", ".cjs", ".mjs", ".css", ".scss"]
|
||||
}),
|
||||
memfs(),
|
||||
progress(argv, logger, mod)
|
||||
],
|
||||
externals: [
|
||||
function ({ context, request }, callback) {
|
||||
if (/^(electron|powercord.*)$/.test(request)) {
|
||||
// Externalize to a commonjs module using the request path
|
||||
return callback(null, "commonjs2 " + request);
|
||||
}
|
||||
|
||||
// Continue without externalizing the import
|
||||
callback();
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
extensions: [
|
||||
".js",
|
||||
".jsx",
|
||||
".ts",
|
||||
".tsx",
|
||||
".coffee",
|
||||
".css",
|
||||
".scss",
|
||||
".sass",
|
||||
".less",
|
||||
".styl",
|
||||
],
|
||||
alias: {
|
||||
ittai: path.resolve(core),
|
||||
react: path.resolve(core, "packages", "react.js"),
|
||||
"react-dom": path.resolve(core, "packages", "react-dom.js"),
|
||||
"react-spring": path.resolve(core, "packages", "react-spring.js"),
|
||||
"lodash": path.resolve(core, "packages", "lodash.js"),
|
||||
"@ittai/config": path.resolve(pluginPath, "ittaiconfig.json")
|
||||
},
|
||||
output: {
|
||||
dir: "./",
|
||||
intro: "// Made with Ittai - https://git.catvibers.me/ittai/ittai\nlet IttaiInternals = {};\nlet ittaiPluginExport=(()=>{",
|
||||
outro: "})();\nif (typeof module !== \"undefined\") module.exports = ittaiPluginExport;\nreturn ittaiPluginExport;",
|
||||
interop: false,
|
||||
format: "iife",
|
||||
// exports: "default",
|
||||
sourcemap: !argv.production ? "inline" : false,
|
||||
sourcemapPathTransform: path =>
|
||||
`file:///${pluginName}/${path}`.replace(
|
||||
/\\/g,
|
||||
'/',
|
||||
),
|
||||
manualChunks: () => "app",
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
usedExports: true,
|
||||
sideEffects: true,
|
||||
minimize: !!argv.production,
|
||||
minimizer: [
|
||||
new TerserPlugin({
|
||||
minify: (file, sourceMap) => {
|
||||
// https://github.com/mishoo/UglifyJS2#minify-options
|
||||
const uglifyJsOptions = {
|
||||
/* your `uglify-js` package options */
|
||||
output: {
|
||||
beautify: true,
|
||||
indent_level: "\t",
|
||||
comments: "some",
|
||||
},
|
||||
mangle: false,
|
||||
compress: {
|
||||
// Enabled
|
||||
dead_code: true,
|
||||
annotations: true,
|
||||
arguments: true,
|
||||
default_values: true,
|
||||
keep_fargs: false,
|
||||
join_vars: true,
|
||||
imports: true,
|
||||
unused: true,
|
||||
side_effects: true,
|
||||
|
||||
// Disabled
|
||||
arrows: false,
|
||||
assignments: false,
|
||||
awaits: false,
|
||||
booleans: false,
|
||||
collapse_vars: false,
|
||||
directives: false,
|
||||
drop_console: false,
|
||||
drop_debugger: false,
|
||||
evaluate: false,
|
||||
expression: false,
|
||||
functions: false,
|
||||
global_defs: false,
|
||||
hoist_exports: false,
|
||||
hoist_funs: false,
|
||||
hoist_props: false,
|
||||
if_return: false,
|
||||
inline: false,
|
||||
keep_infinity: true,
|
||||
loops: false,
|
||||
merge_vars: false,
|
||||
module: false,
|
||||
negate_iife: false,
|
||||
objects: false,
|
||||
properties: true,
|
||||
pure_funcs: null,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: false,
|
||||
reduce_vars: false,
|
||||
rests: false,
|
||||
sequences: false,
|
||||
spreads: false,
|
||||
strings: false,
|
||||
switches: false,
|
||||
templates: false,
|
||||
top_retain: false,
|
||||
toplevel: false,
|
||||
typeofs: false,
|
||||
varify: false,
|
||||
yields: false
|
||||
}
|
||||
};
|
||||
|
||||
if (sourceMap) {
|
||||
uglifyJsOptions.sourceMap = {
|
||||
content: sourceMap,
|
||||
};
|
||||
}
|
||||
|
||||
return require("uglify-js").minify(file, uglifyJsOptions);
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
// {
|
||||
// test: /\.[tj]sx?$/i,
|
||||
// enforce: "pre",
|
||||
// use: ["source-map-loader"],
|
||||
// },
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: [
|
||||
styleLoader,
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
modules: true,
|
||||
import: true,
|
||||
modules: {
|
||||
localIdentName: localFormat
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.s[ac]ss$/i,
|
||||
use: [
|
||||
styleLoader,
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
modules: true,
|
||||
import: true,
|
||||
importLoaders: 1,
|
||||
modules: {
|
||||
localIdentName: localFormat
|
||||
}
|
||||
},
|
||||
},
|
||||
require.resolve("sass-loader"),
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.styl$/i,
|
||||
use: [
|
||||
styleLoader,
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
modules: true,
|
||||
import: true,
|
||||
importLoaders: 1,
|
||||
modules: {
|
||||
localIdentName: localFormat
|
||||
}
|
||||
},
|
||||
},
|
||||
require.resolve("stylus-loader"),
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.less$/i,
|
||||
use: [
|
||||
styleLoader,
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
modules: true,
|
||||
import: true,
|
||||
importLoaders: 1,
|
||||
modules: {
|
||||
localIdentName: localFormat
|
||||
}
|
||||
},
|
||||
},
|
||||
require.resolve("less-loader"),
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.m?jsx?$/i,
|
||||
// exclude: /node_modules/,
|
||||
use: jsBuilder
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/i,
|
||||
use: [
|
||||
tsBuilder,
|
||||
// "ts-loader"
|
||||
],
|
||||
// exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.coffee?$/i,
|
||||
// exclude: /node_modules/,
|
||||
use: [
|
||||
jsBuilder,
|
||||
require.resolve("coffee-loader")
|
||||
], // cool not gonna test it have fun square
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
compiler.outputFileSystem = mockFs;
|
||||
const runCb = (err, stats) => {
|
||||
if (err || stats.hasErrors()) error = { err, stats };
|
||||
stats?.toJson()?.errors?.forEach(e => console.error(e.stack));
|
||||
|
||||
const outputPath = path.join(dist, "index.js");
|
||||
let builtCode = fsMap.get("index.js").toString("utf-8");
|
||||
|
||||
// if (!builtCode.endsWith("})();")) {
|
||||
builtCode = "(()=>{let hasModule;try {module; hasModule = true;}catch(e) {hasModule = false;}" + builtCode + "\nplugin = plugin.default;let ittaiLoadDevMode = false;try{isIttaiLoadingDevMode;ittaiLoadDevMode=true;}catch(e){}let wrappedPlugin = plugin.__ittaiWrap(plugin, ittaiLoadDevMode);if (hasModule) module.exports = wrappedPlugin;return wrappedPlugin;})();";
|
||||
|
||||
// Add clientmod-specific code.
|
||||
builtCode = require("./powercordv2")(builtCode);
|
||||
builtCode = require("./betterdiscord")(builtCode, manifest);
|
||||
builtCode = require("./goosemod")(builtCode);
|
||||
// }
|
||||
// builtCode = beautify(builtCode, {
|
||||
// indent_with_tabs: true,
|
||||
// });
|
||||
|
||||
// // Get rid of ugly blank lines.
|
||||
// builtCode = builtCode.replace(/\n{2,}/g, "\n");
|
||||
if (argv.watch) {
|
||||
if (fs.existsSync(argv.betterdiscord)) {
|
||||
fs.writeFileSync(
|
||||
path.join(argv.betterdiscord, bdFileName),
|
||||
builtCode
|
||||
);
|
||||
onwarn(warning, rollupWarn) {
|
||||
if (warning.code !== 'CIRCULAR_DEPENDENCY' && warning.code !== 'EVAL' && warning.code !== "MISSING_NAME_OPTION_FOR_IIFE_EXPORT") {
|
||||
rollupWarn(warning);
|
||||
}
|
||||
} else {
|
||||
fs.writeFileSync(outputPath, builtCode);
|
||||
|
||||
// fs.copyFileSync(
|
||||
// path.join(pluginPath, "manifest.json"),
|
||||
// path.join(dist, "manifest.json")
|
||||
// );
|
||||
|
||||
fs.writeFileSync(path.join(dist, "manifest.json"), JSON.stringify(manifest))
|
||||
|
||||
if (argv.goosemod) {
|
||||
fs.writeFileSync(path.join(dist, "goosemodModule.json"), JSON.stringify(manifest))
|
||||
}
|
||||
|
||||
if (isValidPath(argv.goosemod)) {
|
||||
fs.ensureDirSync(argv.goosemod);
|
||||
fs.copySync(dist, argv.goosemod);
|
||||
}
|
||||
if (isValidPath(argv.powercordv2)) {
|
||||
fs.ensureDirSync(argv.powercordv2);
|
||||
fs.copySync(dist, argv.powercordv2);
|
||||
}
|
||||
if (fs.existsSync(argv.betterdiscord)) {
|
||||
fs.copyFileSync(
|
||||
path.resolve(path.join(dist, "index.js")),
|
||||
path.join(argv.betterdiscord, bdFileName)
|
||||
);
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
if (argv.watch) {
|
||||
ds && ds.reload(builtCode);
|
||||
}
|
||||
};
|
||||
if (forceNoWatch ? false : argv.watch) {
|
||||
compiler.watch({
|
||||
followSymlinks: true,
|
||||
ignored: ["ittaiTemp", path.join(pluginPath, dist)],
|
||||
}, runCb);
|
||||
} else {
|
||||
compiler.run(runCb);
|
||||
}
|
||||
} else {
|
||||
logger.makeBadge("!", term.bold.bgRed)("Please install Ittai's core or check if the selected plugin folder contains a ").bold.yellow("ittaiconfig.json")(" file. Check ").underline.cyan("https://git.catvibers.me/Ittai/ittai/")(" for more information.\n")
|
||||
term.processExit(1)
|
||||
}
|
||||
|
||||
watcher = rollup.watch(rollupConfig)
|
||||
|
||||
watcher.on("event", async (event) => {
|
||||
switch (event.code) {
|
||||
case "BUNDLE_END":
|
||||
|
||||
const outputs = (await event.result.generate(rollupConfig.output))
|
||||
let builtCode = outputs.output.map(x => x.code).join("\n/*ITTAI CONCAT BUNDLE*/\n");
|
||||
if (!argv.production) {
|
||||
const mapURL = outputs.output.find(x => x.map)?.map.toUrl();
|
||||
builtCode = builtCode + "\n//# sourceMappingURL=" + mapURL;
|
||||
}
|
||||
// builtCode = "(()=>{let IttaiInternals = {};return " + builtCode + "\n})();";
|
||||
|
||||
// Add clientmod-specific code.
|
||||
if (mod == "powercordv2") builtCode = require("./powercordv2")(builtCode);
|
||||
if (mod == "betterdiscord")
|
||||
builtCode = require("./betterdiscord")(builtCode, manifest);
|
||||
if (mod == "betterdiscord") builtCode = require("./goosemod")(builtCode);
|
||||
if (argv.watch) {
|
||||
if (mod == "betterdiscord" && fs.existsSync(argv.betterdiscord)) {
|
||||
fs.writeFileSync(
|
||||
path.join(argv.betterdiscord, bdFileName),
|
||||
builtCode
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (mod == "goosemod" && isValidPath(argv.goosemod)) {
|
||||
fs.ensureDirSync(argv.goosemod);
|
||||
fs.writeFileSync(
|
||||
path.join(argv.goosemod, "index.js"),
|
||||
builtCode
|
||||
);
|
||||
fs.writeFileSync(path.join(argv.goosemod, "goosemodModule.json"), JSON.stringify(manifest))
|
||||
}
|
||||
if (mod == "powercordv2" && isValidPath(argv.powercordv2)) {
|
||||
fs.ensureDirSync(argv.powercordv2);
|
||||
fs.writeFileSync(
|
||||
path.join(argv.powercordv2, "index.js"),
|
||||
builtCode
|
||||
);
|
||||
fs.writeFileSync(path.join(argv.powercordv2, "manifest.json"), JSON.stringify(manifest))
|
||||
}
|
||||
if (mod == "betterdiscord" && isValidPath(argv.betterdiscord)) {
|
||||
fs.ensureDirSync(argv.betterdiscord);
|
||||
fs.writeFileSync(
|
||||
path.join(argv.betterdiscord, bdFileName),
|
||||
builtCode
|
||||
);
|
||||
}
|
||||
}
|
||||
if (argv.watch) {
|
||||
ds && ds.reload(builtCode);
|
||||
}
|
||||
event.result.close();
|
||||
if (!argv.watch) {
|
||||
resolve();
|
||||
watcher.close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.makeBadge("!", term.bold.bgRed)("Please install Ittai's core or check if the selected plugin folder contains a ").bold.yellow("ittaiconfig.json")(" file. Check ").underline.cyan("https://git.catvibers.me/Ittai/ittai/")(" for more information.\n")
|
||||
term.processExit(1)
|
||||
}
|
||||
}));
|
||||
await sleep(1000);
|
||||
}
|
||||
Promise.all(promises).then(() => term.processExit(0)).catch((e) => {
|
||||
term.red("An error occured in the builder, please report this issue.", e)
|
||||
term.processExit(1)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
const path = require("path");
|
||||
const term = require("terminal-kit").terminal;
|
||||
const { highlight } = require('cli-highlight')
|
||||
function nanoseconds() {
|
||||
const hrTime = process.hrtime();
|
||||
return hrTime[0] * 1000000000 + hrTime[1];
|
||||
}
|
||||
|
||||
const modColors = { betterdiscord: term.bold.bgBrightBlue.white, powercordv2: term.bold.bgCyan.black, goosemod: term.bold.bgBlack.white}
|
||||
const modBadges = { betterdiscord: "BD", powercordv2: "PC", goosemod: "GM" }
|
||||
|
||||
module.exports = function createProgressBar(argv, logger, mod) {
|
||||
let total = 0;
|
||||
let last = 0;
|
||||
let startTime;
|
||||
const progressBar = term.progressBar({
|
||||
width: Math.round(term.width / 1.5),
|
||||
title: ` ${modBadges[mod]} ^`,
|
||||
titleStyle: modColors[mod],
|
||||
eta: argv.production ?? false,
|
||||
items: 0,
|
||||
barStyle: term.green,
|
||||
percentStyle: term.green
|
||||
});
|
||||
return {
|
||||
name: "ittaiProgressBar",
|
||||
load(id) {
|
||||
total++;
|
||||
|
||||
progressBar.startItem(id);
|
||||
},
|
||||
transform(_, id) {
|
||||
progressBar.itemDone(id);
|
||||
},
|
||||
buildStart() {
|
||||
startTime = nanoseconds();
|
||||
error = false;
|
||||
if (argv.watch) {
|
||||
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J"); // clears scrollback
|
||||
term.clear();
|
||||
term.moveTo(1, 1);
|
||||
}
|
||||
// progressBar.reset();
|
||||
progressBar.update({items: last})
|
||||
progressBar.resume();
|
||||
progressBar.reset();
|
||||
},
|
||||
buildEnd(error) {
|
||||
term.eraseLine();
|
||||
last = total;
|
||||
total = 0;
|
||||
progressBar.stop();
|
||||
if (error) {
|
||||
errored = true;
|
||||
if (argv.watch) {
|
||||
process.stdout.write("\u001b[3J\u001b[2J\u001b[1J"); // clears scrollback
|
||||
term.clear();
|
||||
term.moveTo(1, 1);
|
||||
}
|
||||
if (error.loc) {
|
||||
term.red(`${error.name}: ${error.message.replace(" in " + error.loc.file, "")}${error.loc ? ` in ${error.loc.file}:${error.loc.line}:${error.loc.column}` : ''}\n`);
|
||||
term(highlight(error.frame, { language: path.extname(error.loc.file).split('.').pop(), ignoreIllegals: true }) + "\n");
|
||||
} else {
|
||||
term.red(error.toString() + "\n");
|
||||
}
|
||||
|
||||
logger.makeBadge("!", term.bold.bgRed)("Build failed after ")
|
||||
.red(`${Math.round((nanoseconds() - startTime) / 1000000).toLocaleString()} ms`)
|
||||
(".\n");
|
||||
if (argv.watch) term.hideCursor();
|
||||
if (!argv.watch) {
|
||||
term.processExit(1)
|
||||
}
|
||||
|
||||
// return resolve();
|
||||
} else {
|
||||
const localeOpts = { minimumIntegerDigits: 2, useGrouping: false }
|
||||
const currentTime = new Date()
|
||||
logger.makeBadge(modBadges[mod], modColors[mod])
|
||||
(`Build done for ${mod}! Built in `)
|
||||
.brightGreen(`${Math.round((nanoseconds() - startTime) / 1000000).toLocaleString()} ms`)
|
||||
(` at `)
|
||||
.cyan(`${currentTime.getHours().toLocaleString(undefined, localeOpts)}:${currentTime.getMinutes().toLocaleString(undefined, localeOpts)}:${currentTime.getSeconds().toLocaleString(undefined, localeOpts)}`)
|
||||
(".\n\n")
|
||||
if (argv.watch) term.hideCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,7 +70,7 @@ module.exports = class DevServer {
|
|||
("On ")
|
||||
.brightCyan(`GooseMod`)
|
||||
(` and `)
|
||||
.brightCyan(`Powercord`)
|
||||
.brightCyan(`Power${"C".toLowerCase()}ord`)
|
||||
(` (make sure to switch to the Electron isolated context in Powercord), run the following code in the console to load your plugin in dev mode:\n`)
|
||||
term.grey(`fetch("http://localhost:3000/client.js").then(r => r.text()).then(r => eval(r))\n\n`)
|
||||
} else {
|
||||
|
|
|
@ -24,5 +24,4 @@ if (!areAllArgsAvaiable || argv.help || argv.h) {
|
|||
}
|
||||
|
||||
const build = require("./build");
|
||||
|
||||
if (areAllArgsAvaiable) build(argv)
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@ittai/builder",
|
||||
"private": false,
|
||||
"version": "1.2.6",
|
||||
"version": "2.0.0",
|
||||
"description": "Ittai Builder",
|
||||
"scripts": {
|
||||
"build-docs": "jsdoc -c jsdoc.json"
|
||||
|
@ -14,42 +14,35 @@
|
|||
"repository": "https://git.catvibers.me/ittai/ittai",
|
||||
"author": "Kyza, AAGaming, A user",
|
||||
"dependencies": {
|
||||
"@swc/core": "^1.2.133",
|
||||
"@rollup/plugin-alias": "^3.1.9",
|
||||
"@rollup/plugin-commonjs": "^22.0.1",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-node-resolve": "^13.3.0",
|
||||
"@rollup/plugin-replace": "^4.0.0",
|
||||
"@types/css": "^0.0.31",
|
||||
"coffee-loader": "^2.0.0",
|
||||
"coffeescript": "^2.6.1",
|
||||
"css-loader": "^5.2.7",
|
||||
"cli-highlight": "^2.1.11",
|
||||
"esbuild": "^0.14.49",
|
||||
"express": "^4.17.2",
|
||||
"extra-watch-webpack-plugin": "^1.0.3",
|
||||
"fork-ts-checker-webpack-plugin": "^7.2.0",
|
||||
"fs-extra": "^9.1.0",
|
||||
"is-valid-path": "^0.1.1",
|
||||
"less": "^4.1.2",
|
||||
"less-loader": "^7.3.0",
|
||||
"rollup": "^2.76.0",
|
||||
"rollup-plugin-esbuild": "^4.9.1",
|
||||
"rollup-plugin-memory-fs": "^1.0.3",
|
||||
"rollup-plugin-styles": "^4.0.0",
|
||||
"sass": "^1.48.0",
|
||||
"sass-loader": "^10.2.1",
|
||||
"style-loader": "^2.0.0",
|
||||
"stylus": "^0.54.8",
|
||||
"stylus-loader": "^4.3.3",
|
||||
"swc-loader": "^0.1.15",
|
||||
"terminal-kit": "^1.49.4",
|
||||
"terser-webpack-plugin": "^5.3.0",
|
||||
"ts-loader": "^9.2.6",
|
||||
"typescript": "^4.5.5",
|
||||
"uglify-js": "^3.16.2",
|
||||
"webpack": "^5.66.0",
|
||||
"ws": "^8.4.2",
|
||||
"yargs": "^17.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"better-docs": "^2.3.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"ignoreMissing": [
|
||||
"react",
|
||||
"react-dom",
|
||||
"prop-types"
|
||||
"prop-types",
|
||||
"webpack"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,7 @@ Building options:\n`)
|
|||
term("\nOther:\n")
|
||||
term.table([
|
||||
['Full argument', 'Abreviation', 'Description'],
|
||||
['--help', "-h", "This help page"]
|
||||
['--help', "-h", "Shows this help page"]
|
||||
], tableOpts)
|
||||
term("\n\n").bold.brightCyan("Note:")(" You can create a configuration file. For more information, run ").inverse("ittai --help=config")
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { React, ModalActions } from "ittai/webpack";
|
||||
import { React, ModalActions } from "../webpack";
|
||||
import * as settings from "../settings";
|
||||
import { Markdown, Modal, Flex, Heading, Text } from "../components";
|
||||
import { Changelog, ChangelogModal } from "../classes";
|
||||
import { changelog as settingsChangelog, manifest } from "@ittai/config"
|
||||
import * as config from "@ittai/config"
|
||||
import { joinClasses } from "../utilities"
|
||||
|
||||
export const renderChangelogContent = (content) => {
|
||||
return <>
|
||||
{Object.entries(content).map(([title, { type, items }]) => <div className={ChangelogModal.content}>
|
||||
|
@ -21,6 +20,7 @@ export const renderChangelogContent = (content) => {
|
|||
}
|
||||
|
||||
export const openChangelogModal = (changelog = settingsChangelog) => {
|
||||
const { changelog: settingsChangelog, manifest } = config;
|
||||
ModalActions.openModal((props) => <Modal.ModalRoot {...props} size={Modal.ModalSize.SMALL} className={ChangelogModal.modal}>
|
||||
<Modal.ModalHeader separator={false}>
|
||||
<Flex>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { findByProps } from "../webpack";
|
||||
|
||||
export const Changelog = findByProps("lead", "socialLink")
|
||||
export const ChangelogModal = findByProps("maxModalWidth", "content") //i assume its related to the changelog modal
|
||||
export const Margins = findByProps("marginLarge", "marginTop20")
|
||||
export const CardLook = findByProps("arrow", "container", "description")
|
||||
export const Changelog = /*#__PURE__*/ findByProps("lead", "socialLink")
|
||||
export const ChangelogModal = /*#__PURE__*/ findByProps("maxModalWidth", "content") //i assume its related to the changelog modal
|
||||
export const Margins = /*#__PURE__*/ findByProps("marginLarge", "marginTop20")
|
||||
export const CardLook = /*#__PURE__*/ findByProps("arrow", "container", "description")
|
|
@ -1,18 +0,0 @@
|
|||
.category {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.category-header-icon{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
color: var(--interactive-active);
|
||||
}
|
||||
|
||||
.category-header-icon.closed{
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.category-content {
|
||||
margin-top: 16px;
|
||||
padding: 0 20px;
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { React } from "ittai/webpack";
|
||||
import styles from "./Category.css"
|
||||
import { React } from "../webpack";
|
||||
import DiscordIcon from "./DiscordIcon";
|
||||
import { Text, Forms } from "./index";
|
||||
import { Text } from "./index";
|
||||
import { CardLook } from "../classes";
|
||||
|
||||
/**
|
||||
|
@ -22,7 +21,7 @@ import { CardLook } from "../classes";
|
|||
export default function Category({ title, description, icon, children, openedByDefault = false }) {
|
||||
const [opened, setOpened] = React.useState(openedByDefault);
|
||||
|
||||
return <div className={styles["category"]}>
|
||||
return <div styles={{marginBottom: "20px"}}>
|
||||
<div className={CardLook.container} onClick={() => setOpened(!opened)}>
|
||||
{icon && <div className={CardLook.icon}>
|
||||
<DiscordIcon name={icon} style={{width: "20px", height: "20px"}} />
|
||||
|
@ -32,11 +31,11 @@ export default function Category({ title, description, icon, children, openedByD
|
|||
{description && <Text>{description}</Text>}
|
||||
</div>
|
||||
<div className={CardLook.arrow}>
|
||||
<DiscordIcon name="DropdownArrow" className={`${styles["category-header-icon"]} ${!opened ? styles["closed"] : ""}`} />
|
||||
<DiscordIcon name="DropdownArrow" style={{width: "24px", height: "24px", color: "var(--interactive-active)", transform: !opened ? "rotate(-90deg)" : void 0}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{opened && <div className={styles["category-content"]}>{children}</div>}
|
||||
{opened && <div style={{marginTop: "16px", padding: "0 20px"}}>{children}</div>}
|
||||
|
||||
{/* <Forms.FormDivider className="dividerDefault-3C2-ws"/> */}
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { React } from "ittai/webpack";
|
||||
import { React } from "../webpack";
|
||||
import { findByProps, findByDisplayName } from "../webpack";
|
||||
|
||||
const classes = {
|
||||
default: findByProps("icon", "selected").icon,
|
||||
contextmenu: findByProps("icon", "submenu").icon,
|
||||
minipopover: findByProps("icon", "isHeader").icon,
|
||||
default: /*#__PURE__*/(()=>findByProps("icon", "selected").icon)(),
|
||||
contextmenu: /*#__PURE__*/(()=>findByProps("icon", "submenu").icon)(),
|
||||
minipopover: /*#__PURE__*/(()=>findByProps("icon", "isHeader").icon)(),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { React } from "ittai/webpack";
|
||||
import { React } from "../webpack";
|
||||
import { findByProps } from "../webpack";
|
||||
|
||||
const LayerProvider = findByProps("AppLayerProvider").AppLayerProvider().props.layerContext
|
||||
.Provider;
|
||||
const AccessibilityProvider = findByProps(
|
||||
const LayerProvider = /*#__PURE__*/(()=>findByProps("AppLayerProvider").AppLayerProvider().props.layerContext
|
||||
.Provider)();
|
||||
const AccessibilityProvider = /*#__PURE__*/(()=>findByProps(
|
||||
"AccessibilityPreferencesContext"
|
||||
).AccessibilityPreferencesContext.Provider;
|
||||
const layerClass = findByProps("LayerClassName").LayerClassName;
|
||||
).AccessibilityPreferencesContext.Provider)();
|
||||
const layerClass = /*#__PURE__*/(()=>findByProps("LayerClassName").LayerClassName)();
|
||||
|
||||
/**
|
||||
* Wrap a component rendered out-of-tree in Discord's providers
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { React, Flux } from "ittai/webpack";
|
||||
import { React, Flux } from "../webpack";
|
||||
|
||||
export default function FluxWrapper(props) {
|
||||
if (!props.children.displayName) props.children.displayName = "FluxProxy";
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
|
||||
import { React, findByDisplayName, findByProps, find } from "../webpack";
|
||||
|
||||
// Don't re-export our components as they won't treeshake properly. Instead, people can manually import them.
|
||||
export { default as DiscordIcon } from "./DiscordIcon";
|
||||
export { default as DiscordProviders } from "./DiscordProviders";
|
||||
export { default as FluxWrapper } from "./FluxWrapper";
|
||||
export { default as Category } from "./Category";
|
||||
|
||||
// Wrapper for Switch component to make the switch box not being updatable. Check https://github.com/BetterDiscordBuilder/bdbuilder/blob/master/common/hooks/createUpdateWrapper.js
|
||||
// Wrapper for Switch component to fix the switch box not being updatable. Check https://github.com/BetterDiscordBuilder/bdbuilder/blob/master/common/hooks/createUpdateWrapper.js
|
||||
export const makeUpdateWrapper = (Component, checkPropName = "value", type = "switch") => {
|
||||
const typeSwitch = (v) => {
|
||||
switch (type) {
|
||||
|
@ -40,47 +41,44 @@ export const makeUpdateWrapper = (Component, checkPropName = "value", type = "sw
|
|||
}
|
||||
}
|
||||
|
||||
export const Button = findByProps("Colors", "Looks", "DropdownSizes");
|
||||
export const Spinner = findByDisplayName("Spinner");
|
||||
export const Text = findByDisplayName("LegacyText");
|
||||
export const TextInput = findByDisplayName("TextInput");
|
||||
export const Tooltip = findByDisplayName("Tooltip");
|
||||
export const TooltipContainer = findByProps("TooltipContainer")?.TooltipContainer;
|
||||
export const SlideIn = findByDisplayName("SlideIn");
|
||||
export const SettingsNotice = findByDisplayName("SettingsNotice");
|
||||
export const TransitionGroup = findByDisplayName("TransitionGroup");
|
||||
export const Flex = findByDisplayName("Flex");
|
||||
export const Card = findByDisplayName("Card");
|
||||
export const Popout = findByDisplayName("Popout");
|
||||
export const Progress = findByDisplayName("Progress");
|
||||
export const Modal = findByProps("ModalRoot")
|
||||
export const Forms = findByProps('FormItem')
|
||||
export const ColorPicker = findByDisplayName("ColorPicker")
|
||||
export const Anchor = findByDisplayName("Anchor")
|
||||
export const Heading = findByProps("Heading").Heading
|
||||
export const KeyboardShortcut = findByProps("PRETTY_KEYS").default
|
||||
export const SearchBar = findByProps("SearchIcon").default
|
||||
export const OriginalRadioGroup = findByDisplayName("RadioGroup");
|
||||
export const Button = /*#__PURE__*/findByProps("Colors", "Looks", "DropdownSizes");
|
||||
export const Spinner = /*#__PURE__*/findByDisplayName("Spinner");
|
||||
export const Text = /*#__PURE__*/findByDisplayName("LegacyText");
|
||||
export const TextInput = /*#__PURE__*/findByDisplayName("TextInput");
|
||||
export const Tooltip = /*#__PURE__*/findByDisplayName("Tooltip");
|
||||
export const TooltipContainer = /*#__PURE__*/(() => findByProps("TooltipContainer")?.TooltipContainer)();
|
||||
export const SlideIn = /*#__PURE__*/findByDisplayName("SlideIn");
|
||||
export const SettingsNotice = /*#__PURE__*/findByDisplayName("SettingsNotice");
|
||||
export const TransitionGroup = /*#__PURE__*/findByDisplayName("TransitionGroup");
|
||||
export const Flex = /*#__PURE__*/findByDisplayName("Flex");
|
||||
export const Card = /*#__PURE__*/findByDisplayName("Card");
|
||||
export const Popout = /*#__PURE__*/findByDisplayName("Popout");
|
||||
export const Progress = /*#__PURE__*/findByDisplayName("Progress");
|
||||
export const Modal = /*#__PURE__*/findByProps("ModalRoot")
|
||||
export const Forms = /*#__PURE__*/findByProps('FormItem')
|
||||
export const ColorPicker = /*#__PURE__*/findByDisplayName("ColorPicker")
|
||||
export const Anchor = /*#__PURE__*/findByDisplayName("Anchor")
|
||||
export const Heading = /*#__PURE__*/(() => findByProps("Heading").Heading)();
|
||||
export const KeyboardShortcut = /*#__PURE__*/(() => findByProps("PRETTY_KEYS").default)();
|
||||
export const SearchBar = /*#__PURE__*/(() => findByProps("SearchIcon").default)();
|
||||
export const OriginalRadioGroup = /*#__PURE__*/findByDisplayName("RadioGroup");
|
||||
export const RadioGroup = makeUpdateWrapper(OriginalRadioGroup, "value", "radio");
|
||||
export const OriginalSwitch = findByDisplayName("Switch");
|
||||
export const OriginalSwitch = /*#__PURE__*/findByDisplayName("Switch");
|
||||
export const Switch = makeUpdateWrapper(OriginalSwitch, "checked");
|
||||
export const OriginalSwitchItem = findByDisplayName("SwitchItem");
|
||||
export const OriginalSwitchItem = /*#__PURE__*/findByDisplayName("SwitchItem");
|
||||
export const SwitchItem = makeUpdateWrapper(OriginalSwitchItem, "value");
|
||||
export const Markdown = find(m => m?.default?.displayName == "Markdown" && m?.default?.rules)?.default
|
||||
export const Markdown = /*#__PURE__*/(() => find(m => m?.default?.displayName == "Markdown" && m?.default?.rules)?.default)();
|
||||
|
||||
export const ContextMenu = findByProps("MenuItem").default
|
||||
export const ContextMenu = /*#__PURE__*/findByProps("MenuItem").default
|
||||
Object.entries(findByProps("MenuItem")).forEach(([key, contents]) => {
|
||||
if (!ContextMenu[key]) {
|
||||
ContextMenu[key] = contents
|
||||
}
|
||||
})
|
||||
|
||||
export const Avatar = findByProps("AnimatedAvatar").default
|
||||
Object.entries(findByProps("AnimatedAvatar")).forEach(([key, contents]) => {
|
||||
if (!Avatar[key]) {
|
||||
Avatar[key] = contents
|
||||
}
|
||||
})
|
||||
export const Avatar = /*#__PURE__*/(() => findByProps("AnimatedAvatar").default)()
|
||||
export const AnimatedAvatar = /*#__PURE__*/(() => findByProps("AnimatedAvatar").AnimatedAvatar)()
|
||||
export const AvatarSizes = /*#__PURE__*/(() => findByProps("AnimatedAvatar").Sizes)()
|
||||
|
||||
export const Slider = findByProps("MarkerPositions").default
|
||||
Slider.MarkerPositions = findByProps("MarkerPositions").MarkerPositions
|
||||
export const Slider = /*#__PURE__*/(() => findByProps("MarkerPositions").default)()
|
||||
export const SliderMarkerPositions = /*#__PURE__*/(() => findByProps("MarkerPositions").MarkerPositions)()
|
|
@ -1,4 +1,3 @@
|
|||
import { getClientMod } from "ittai/utilities";
|
||||
import { manifest as pluginManifest } from "@ittai/config";
|
||||
const {name} = pluginManifest
|
||||
|
||||
|
@ -6,7 +5,7 @@ class WSManager {
|
|||
start () {
|
||||
this.ws = new WebSocket('ws://localhost:3000');
|
||||
this.ws.addEventListener('open', () => {
|
||||
this.ws.send(`identify,${getClientMod()}`);
|
||||
this.ws.send(`identify,${process.env.CLIENT_MOD}`);
|
||||
});
|
||||
|
||||
this.ws.addEventListener('message', (data) => {
|
||||
|
@ -56,15 +55,14 @@ export function reloadPlugin() {
|
|||
fetch("http://localhost:3000/plugin.js").then(r => r.text()).then(data => {
|
||||
let __ITTAI_DEVSERVER_VERSION__ = version;
|
||||
let __ITTAI_DEVSERVER_INSTANCE__ = { version, startDevServer, stopDevServer, reloadPlugin, loadPlugin, manager };
|
||||
let _plugin = plugin;
|
||||
plugin = undefined;
|
||||
// Keep this log so rollup doesn't delete these variables
|
||||
console.debug("reloading using instance", __ITTAI_DEVSERVER_INSTANCE__, "version", __ITTAI_DEVSERVER_VERSION__)
|
||||
const instance = eval(data);
|
||||
loadPlugin(instance);
|
||||
})
|
||||
}
|
||||
|
||||
export async function loadPlugin(p) {
|
||||
let mod = getClientMod();
|
||||
let mod = process.env.CLIENT_MOD;
|
||||
|
||||
switch (mod) {
|
||||
case "goosemod":
|
||||
|
@ -76,7 +74,7 @@ export async function loadPlugin(p) {
|
|||
try {
|
||||
window.powercord.pluginManager.unload(name);
|
||||
} catch (e) {
|
||||
!e.toString().startsWith("Tried to unload a non installed plugin (undefined)") && console.log(e)
|
||||
!e.toString().startsWith("Error: Tried to unload a non installed plugin (undefined)") && console.log(e)
|
||||
}
|
||||
const manifest = Object.assign({
|
||||
appMode: 'app',
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { getClientMod } from "ittai/utilities";
|
||||
|
||||
import * as DevClient from "./client.js";
|
||||
let hasDevServer = false;
|
||||
|
||||
export default async function loadDevServer() {
|
||||
if (getClientMod() === "betterdiscord") return
|
||||
if (__ITTAI_DEV__ && __ITTAI_WATCH__) {
|
||||
export async function loadDevServer() {
|
||||
if (process.env.DEV_MODE == "true") {
|
||||
if (process.env.CLIENT_MOD === "betterdiscord") return
|
||||
hasDevServer = true;
|
||||
try { __ITTAI_DEVSERVER_VERSION__; } catch (_) { console.log("no server"); hasDevServer = false; } // check for variable, js is weird
|
||||
const version = (await import("./client")).version
|
||||
const version = DevClient.version
|
||||
if (hasDevServer && __ITTAI_DEVSERVER_VERSION__ !== version) {
|
||||
console.log("Upgrading dev server client")
|
||||
__ITTAI_DEVSERVER_INSTANCE__.stopDevServer()
|
||||
|
@ -16,20 +15,22 @@ export default async function loadDevServer() {
|
|||
if (hasDevServer) {
|
||||
console.log("Using existing dev server client")
|
||||
}
|
||||
}
|
||||
if (!hasDevServer && __ITTAI_DEV__ && __ITTAI_WATCH__) {
|
||||
console.log("Loading dev server client")
|
||||
import("./client").then(m => m.default());
|
||||
if (!hasDevServer) {
|
||||
console.log("Loading dev server client")
|
||||
DevClient.default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function loadDevPlugin(p) {
|
||||
if (getClientMod() === "betterdiscord") return
|
||||
if (hasDevServer) {
|
||||
console.log("Loading using existing dev server client")
|
||||
__ITTAI_DEVSERVER_INSTANCE__.loadPlugin(p)
|
||||
} else if (__ITTAI_DEV__ && __ITTAI_WATCH__) {
|
||||
console.log("Loading plugin using new dev server client")
|
||||
import("./client").then(m => m.loadPlugin(p));
|
||||
if (process.env.DEV_MODE == "true") {
|
||||
if (process.env.CLIENT_MOD === "betterdiscord") return
|
||||
if (hasDevServer) {
|
||||
console.log("Loading using existing dev server client")
|
||||
__ITTAI_DEVSERVER_INSTANCE__.loadPlugin(p)
|
||||
} else {
|
||||
console.log("Loading plugin using new dev server client")
|
||||
DevClient.loadPlugin(p);
|
||||
}
|
||||
}
|
||||