@ -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 )
// 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 }
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]"
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 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"
}
}
}
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"'
}
}
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"),
// }),
] ,
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 ( ) ;
} ,
nodeResolve ( {
extensions : [ ".ts" , ".tsx" , ".jsx" , ".js" , ".cjs" , ".mjs" , ".css" , ".scss" ]
} ) ,
memfs ( ) ,
progress ( argv , logger , mod )
] ,
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" )
} ,
} ,
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
} ,
] ,
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" ,
} ,
} ) ;
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")
// );
watcher = rollup . watch ( rollupConfig )
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 ) ;
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 ;
}
} ;
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 )
}
} ) ;
} 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 )
} ) ;
}