Skip to content

Commit

Permalink
fix: revert cli stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
twlite committed Dec 13, 2024
1 parent 219fd84 commit 5f7a48e
Show file tree
Hide file tree
Showing 39 changed files with 4,080 additions and 3,341 deletions.
107 changes: 107 additions & 0 deletions packages/commandkit/bin/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// @ts-check

import { readFile, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { build } from 'tsup';
import { Colors, erase, findCommandKitConfig, panic, write } from './common.mjs';
import ora from 'ora';

export async function bootstrapProductionBuild(config) {
const {
sourcemap = false,
minify = false,
outDir = 'dist',
antiCrash = true,
src,
main,
requirePolyfill: polyfillRequire,
} = await findCommandKitConfig(config);

const status = ora('Creating optimized production build...\n').start();
const start = performance.now();

erase(outDir);

try {
await build({
clean: true,
format: ['esm'],
dts: false,
skipNodeModulesBundle: true,
minify,
shims: true,
banner: {
js: '/* Optimized production build generated by CommandKit */',
},
sourcemap,
keepNames: true,
outDir,
silent: true,
watch: false,
entry: [src, '!dist', '!.commandkit', `!${outDir}`],
});

await injectShims(outDir, main, antiCrash, polyfillRequire);

status.succeed(
Colors.green(`Build completed in ${(performance.now() - start).toFixed(2)}ms!`),
);
write(
Colors.green(
`\nRun ${Colors.magenta(`commandkit start`)} ${Colors.green('to start your bot.')}`,
),
);
} catch (e) {
status.fail(`Build failed after ${(performance.now() - start).toFixed(2)}ms!`);
panic(e);
}
}

export async function injectShims(outDir, main, antiCrash, polyfillRequire) {
const path = join(process.cwd(), outDir, main);

const head = ['\n\n;await (async()=>{', " 'use strict';"].join('\n');
const tail = '\n})();';
const requireScript = polyfillRequire
? [
'// --- CommandKit require() polyfill ---',
' if (typeof require === "undefined") {',
' const { createRequire } = await import("node:module");',
' const __require = createRequire(import.meta.url);',
' Object.defineProperty(globalThis, "require", {',
' value: (id) => {',
' return __require(id);',
' },',
' configurable: true,',
' enumerable: false,',
' writable: true,',
' });',
' }',
'// --- CommandKit require() polyfill ---',
].join('\n')
: '';

const antiCrashScript = antiCrash
? [
'// --- CommandKit Anti-Crash Monitor ---',
" // 'uncaughtException' event is supposed to be used to perform synchronous cleanup before shutting down the process",
' // instead of using it as a means to resume operation.',
' // But it exists here due to compatibility reasons with discord bot ecosystem.',
" const p = (t) => `\\x1b[33m${t}\\x1b[0m`, b = '[CommandKit Anti-Crash Monitor]', l = console.log, e1 = 'uncaughtException', e2 = 'unhandledRejection';",
' if (!process.eventNames().includes(e1)) // skip if it is already handled',
' process.on(e1, (e) => {',
' l(p(`${b} Uncaught Exception`)); l(p(b), p(e.stack || e));',
' })',
' if (!process.eventNames().includes(e2)) // skip if it is already handled',
' process.on(e2, (r) => {',
' l(p(`${b} Unhandled promise rejection`)); l(p(`${b} ${r.stack || r}`));',
' });',
'// --- CommandKit Anti-Crash Monitor ---',
].join('\n')
: '';

const contents = await readFile(path, 'utf-8');
const finalScript = [head, requireScript, antiCrashScript, tail, '\n\n', contents].join('\n');

return writeFile(path, finalScript);
}
122 changes: 122 additions & 0 deletions packages/commandkit/bin/common.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// @ts-check

import { rimrafSync } from 'rimraf';
import { join } from 'node:path';
import fs from 'node:fs';

const resetColor = '\x1b[0m';

export const Colors = {
reset: (text) => `${text}${resetColor}`,
bright: (text) => `\x1b[1m${text}${resetColor}`,
dim: (text) => `\x1b[2m${text}${resetColor}`,
underscore: (text) => `\x1b[4m${text}${resetColor}`,
blink: (text) => `\x1b[5m${text}${resetColor}`,
reverse: (text) => `\x1b[7m${text}${resetColor}`,
hidden: (text) => `\x1b[8m${text}${resetColor}`,

black: (text) => `\x1b[30m${text}${resetColor}`,
red: (text) => `\x1b[31m${text}${resetColor}`,
green: (text) => `\x1b[32m${text}${resetColor}`,
yellow: (text) => `\x1b[33m${text}${resetColor}`,
blue: (text) => `\x1b[34m${text}${resetColor}`,
magenta: (text) => `\x1b[35m${text}${resetColor}`,
cyan: (text) => `\x1b[36m${text}${resetColor}`,
white: (text) => `\x1b[37m${text}${resetColor}`,

bgBlack: (text) => `\x1b[40m${text}${resetColor}`,
bgRed: (text) => `\x1b[41m${text}${resetColor}`,
bgGreen: (text) => `\x1b[42m${text}${resetColor}`,
bgYellow: (text) => `\x1b[43m${text}${resetColor}`,
bgBlue: (text) => `\x1b[44m${text}${resetColor}`,
bgMagenta: (text) => `\x1b[45m${text}${resetColor}`,
bgCyan: (text) => `\x1b[46m${text}${resetColor}`,
bgWhite: (text) => `\x1b[47m${text}${resetColor}`,
};

export function write(message) {
process.stdout.write(message);
process.stdout.write('\n');
}

/**
* @returns {never}
*/
export function panic(message) {
write(Colors.red(`Error: ${message}`));
process.exit(1);
}

export function findPackageJSON() {
const cwd = process.cwd();
const target = join(cwd, 'package.json');

if (!fs.existsSync(target)) {
panic('Could not find package.json in current directory.');
}

return JSON.parse(fs.readFileSync(target, 'utf8'));
}

const possibleFileNames = [
'commandkit.json',
'commandkit.config.json',
'commandkit.js',
'commandkit.config.js',
'commandkit.mjs',
'commandkit.config.mjs',
'commandkit.cjs',
'commandkit.config.cjs',
'commandkit.ts',
'commandkit.mts',
'commandkit.cts',
];

export async function findCommandKitConfig(src) {
const cwd = process.cwd();
const locations = src ? [join(cwd, src)] : possibleFileNames.map((name) => join(cwd, name));

for (const location of locations) {
try {
return await loadConfigInner(location);
} catch (e) {
continue;
}
}

panic(`Could not locate commandkit config from ${cwd}`);
}


function ensureTypeScript(target) {
const isTypeScript = /\.(c|m)tsx?$/.test(target);

if (isTypeScript && !process.features.typescript) {
panic('You are trying to load commandkit config file that is written in typescript. The current Node.js version does not have TypeScript feature enabled.');
}
}

async function loadConfigInner(target) {
const isJSON = target.endsWith('.json');

await ensureExists(target);

ensureTypeScript(target);

/**
* @type {import('..').CommandKitConfig}
*/
const config = await import(`file://${target}`, {
assert: isJSON ? { type: 'json' } : undefined,
}).then((conf) => conf.default || conf);

return config;
}

async function ensureExists(loc) {
await fs.promises.access(loc, fs.constants.F_OK);
}

export function erase(dir) {
rimrafSync(dir);
}
Loading

0 comments on commit 5f7a48e

Please sign in to comment.