Skip to content

Commit 5f7a48e

Browse files
committed
fix: revert cli stuff
1 parent 219fd84 commit 5f7a48e

39 files changed

+4080
-3341
lines changed

packages/commandkit/bin/build.mjs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// @ts-check
2+
3+
import { readFile, writeFile } from 'node:fs/promises';
4+
import { join } from 'node:path';
5+
import { build } from 'tsup';
6+
import { Colors, erase, findCommandKitConfig, panic, write } from './common.mjs';
7+
import ora from 'ora';
8+
9+
export async function bootstrapProductionBuild(config) {
10+
const {
11+
sourcemap = false,
12+
minify = false,
13+
outDir = 'dist',
14+
antiCrash = true,
15+
src,
16+
main,
17+
requirePolyfill: polyfillRequire,
18+
} = await findCommandKitConfig(config);
19+
20+
const status = ora('Creating optimized production build...\n').start();
21+
const start = performance.now();
22+
23+
erase(outDir);
24+
25+
try {
26+
await build({
27+
clean: true,
28+
format: ['esm'],
29+
dts: false,
30+
skipNodeModulesBundle: true,
31+
minify,
32+
shims: true,
33+
banner: {
34+
js: '/* Optimized production build generated by CommandKit */',
35+
},
36+
sourcemap,
37+
keepNames: true,
38+
outDir,
39+
silent: true,
40+
watch: false,
41+
entry: [src, '!dist', '!.commandkit', `!${outDir}`],
42+
});
43+
44+
await injectShims(outDir, main, antiCrash, polyfillRequire);
45+
46+
status.succeed(
47+
Colors.green(`Build completed in ${(performance.now() - start).toFixed(2)}ms!`),
48+
);
49+
write(
50+
Colors.green(
51+
`\nRun ${Colors.magenta(`commandkit start`)} ${Colors.green('to start your bot.')}`,
52+
),
53+
);
54+
} catch (e) {
55+
status.fail(`Build failed after ${(performance.now() - start).toFixed(2)}ms!`);
56+
panic(e);
57+
}
58+
}
59+
60+
export async function injectShims(outDir, main, antiCrash, polyfillRequire) {
61+
const path = join(process.cwd(), outDir, main);
62+
63+
const head = ['\n\n;await (async()=>{', " 'use strict';"].join('\n');
64+
const tail = '\n})();';
65+
const requireScript = polyfillRequire
66+
? [
67+
'// --- CommandKit require() polyfill ---',
68+
' if (typeof require === "undefined") {',
69+
' const { createRequire } = await import("node:module");',
70+
' const __require = createRequire(import.meta.url);',
71+
' Object.defineProperty(globalThis, "require", {',
72+
' value: (id) => {',
73+
' return __require(id);',
74+
' },',
75+
' configurable: true,',
76+
' enumerable: false,',
77+
' writable: true,',
78+
' });',
79+
' }',
80+
'// --- CommandKit require() polyfill ---',
81+
].join('\n')
82+
: '';
83+
84+
const antiCrashScript = antiCrash
85+
? [
86+
'// --- CommandKit Anti-Crash Monitor ---',
87+
" // 'uncaughtException' event is supposed to be used to perform synchronous cleanup before shutting down the process",
88+
' // instead of using it as a means to resume operation.',
89+
' // But it exists here due to compatibility reasons with discord bot ecosystem.',
90+
" const p = (t) => `\\x1b[33m${t}\\x1b[0m`, b = '[CommandKit Anti-Crash Monitor]', l = console.log, e1 = 'uncaughtException', e2 = 'unhandledRejection';",
91+
' if (!process.eventNames().includes(e1)) // skip if it is already handled',
92+
' process.on(e1, (e) => {',
93+
' l(p(`${b} Uncaught Exception`)); l(p(b), p(e.stack || e));',
94+
' })',
95+
' if (!process.eventNames().includes(e2)) // skip if it is already handled',
96+
' process.on(e2, (r) => {',
97+
' l(p(`${b} Unhandled promise rejection`)); l(p(`${b} ${r.stack || r}`));',
98+
' });',
99+
'// --- CommandKit Anti-Crash Monitor ---',
100+
].join('\n')
101+
: '';
102+
103+
const contents = await readFile(path, 'utf-8');
104+
const finalScript = [head, requireScript, antiCrashScript, tail, '\n\n', contents].join('\n');
105+
106+
return writeFile(path, finalScript);
107+
}

packages/commandkit/bin/common.mjs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// @ts-check
2+
3+
import { rimrafSync } from 'rimraf';
4+
import { join } from 'node:path';
5+
import fs from 'node:fs';
6+
7+
const resetColor = '\x1b[0m';
8+
9+
export const Colors = {
10+
reset: (text) => `${text}${resetColor}`,
11+
bright: (text) => `\x1b[1m${text}${resetColor}`,
12+
dim: (text) => `\x1b[2m${text}${resetColor}`,
13+
underscore: (text) => `\x1b[4m${text}${resetColor}`,
14+
blink: (text) => `\x1b[5m${text}${resetColor}`,
15+
reverse: (text) => `\x1b[7m${text}${resetColor}`,
16+
hidden: (text) => `\x1b[8m${text}${resetColor}`,
17+
18+
black: (text) => `\x1b[30m${text}${resetColor}`,
19+
red: (text) => `\x1b[31m${text}${resetColor}`,
20+
green: (text) => `\x1b[32m${text}${resetColor}`,
21+
yellow: (text) => `\x1b[33m${text}${resetColor}`,
22+
blue: (text) => `\x1b[34m${text}${resetColor}`,
23+
magenta: (text) => `\x1b[35m${text}${resetColor}`,
24+
cyan: (text) => `\x1b[36m${text}${resetColor}`,
25+
white: (text) => `\x1b[37m${text}${resetColor}`,
26+
27+
bgBlack: (text) => `\x1b[40m${text}${resetColor}`,
28+
bgRed: (text) => `\x1b[41m${text}${resetColor}`,
29+
bgGreen: (text) => `\x1b[42m${text}${resetColor}`,
30+
bgYellow: (text) => `\x1b[43m${text}${resetColor}`,
31+
bgBlue: (text) => `\x1b[44m${text}${resetColor}`,
32+
bgMagenta: (text) => `\x1b[45m${text}${resetColor}`,
33+
bgCyan: (text) => `\x1b[46m${text}${resetColor}`,
34+
bgWhite: (text) => `\x1b[47m${text}${resetColor}`,
35+
};
36+
37+
export function write(message) {
38+
process.stdout.write(message);
39+
process.stdout.write('\n');
40+
}
41+
42+
/**
43+
* @returns {never}
44+
*/
45+
export function panic(message) {
46+
write(Colors.red(`Error: ${message}`));
47+
process.exit(1);
48+
}
49+
50+
export function findPackageJSON() {
51+
const cwd = process.cwd();
52+
const target = join(cwd, 'package.json');
53+
54+
if (!fs.existsSync(target)) {
55+
panic('Could not find package.json in current directory.');
56+
}
57+
58+
return JSON.parse(fs.readFileSync(target, 'utf8'));
59+
}
60+
61+
const possibleFileNames = [
62+
'commandkit.json',
63+
'commandkit.config.json',
64+
'commandkit.js',
65+
'commandkit.config.js',
66+
'commandkit.mjs',
67+
'commandkit.config.mjs',
68+
'commandkit.cjs',
69+
'commandkit.config.cjs',
70+
'commandkit.ts',
71+
'commandkit.mts',
72+
'commandkit.cts',
73+
];
74+
75+
export async function findCommandKitConfig(src) {
76+
const cwd = process.cwd();
77+
const locations = src ? [join(cwd, src)] : possibleFileNames.map((name) => join(cwd, name));
78+
79+
for (const location of locations) {
80+
try {
81+
return await loadConfigInner(location);
82+
} catch (e) {
83+
continue;
84+
}
85+
}
86+
87+
panic(`Could not locate commandkit config from ${cwd}`);
88+
}
89+
90+
91+
function ensureTypeScript(target) {
92+
const isTypeScript = /\.(c|m)tsx?$/.test(target);
93+
94+
if (isTypeScript && !process.features.typescript) {
95+
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.');
96+
}
97+
}
98+
99+
async function loadConfigInner(target) {
100+
const isJSON = target.endsWith('.json');
101+
102+
await ensureExists(target);
103+
104+
ensureTypeScript(target);
105+
106+
/**
107+
* @type {import('..').CommandKitConfig}
108+
*/
109+
const config = await import(`file://${target}`, {
110+
assert: isJSON ? { type: 'json' } : undefined,
111+
}).then((conf) => conf.default || conf);
112+
113+
return config;
114+
}
115+
116+
async function ensureExists(loc) {
117+
await fs.promises.access(loc, fs.constants.F_OK);
118+
}
119+
120+
export function erase(dir) {
121+
rimrafSync(dir);
122+
}

0 commit comments

Comments
 (0)