Merge branch 'dev' into 'main'

Added bun bundle

See merge request illegitimate/illegitimate-bot!349
This commit is contained in:
2025-08-10 20:58:47 +02:00
16 changed files with 88 additions and 98 deletions

View File

@@ -1,10 +1,7 @@
.git .git
.nodemon
.vscode
dev dev
dist dist
node_modules node_modules
scripts
.dockerignore .dockerignore
.env .env
.env.example .env.example

33
.swcrc
View File

@@ -1,33 +0,0 @@
{
"$schema": "https://swc.rs/schema.json",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"dynamicImport": true,
"decorators": false
},
"target": "es2022",
"loose": false,
"externalHelpers": false,
"keepClassNames": false,
"preserveAllComments": false,
"baseUrl": "./",
"paths": {
"~/utils/*": ["src/utils/*"],
"~/config/*": ["src/config/*"],
"~/typings": ["src/typings/index"]
}
},
"module": {
"type": "es6",
"strict": true,
"strictMode": true,
"noInterop": false,
"lazy": false,
"ignoreDynamic": true,
"resolveFully": true
},
"minify": false,
"sourceMaps": false
}

25
.vscode/launch.json vendored
View File

@@ -1,25 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to process (nvim)",
"type": "pwa-node",
"request": "attach",
"port": 9229,
"skipFiles": [
"<node_internals>/**",
"${workspaceFolder}/node_modules/**"
]
},
{
"name": "Attach to process (vscode)",
"type": "node",
"request": "attach",
"port": 9229,
"skipFiles": [
"<node_internals>/**",
"${workspaceFolder}/node_modules/**"
]
}
]
}

View File

@@ -1,11 +1,17 @@
FROM oven/bun FROM oven/bun AS build
WORKDIR /app WORKDIR /app
COPY package.json bun.lock . COPY package.json bun.lock .
RUN bun install --production --frozen-lockfile RUN bun install --frozen-lockfile
COPY . . COPY . .
ENV NODE_ENV prod ENV NODE_ENV=prod
RUN bun bundle
CMD ["bun", "run", "start"] FROM oven/bun
WORKDIR /app
COPY --from=build /app/dist /app
CMD ["bun", "run", "index.js"]

View File

@@ -10,9 +10,13 @@ services:
- HYPIXELAPIKEY=${HYPIXELAPIKEY} - HYPIXELAPIKEY=${HYPIXELAPIKEY}
- REDISURI=${REDISURI} - REDISURI=${REDISURI}
- POSTGRESURI=${POSTGRESURI} - POSTGRESURI=${POSTGRESURI}
- PG_USER=${PG_USER}
- PG_PASSWORD=${PG_PASSWORD}
- PG_HOST=${PG_HOST}
- PG_PORT=${PG_PORT}
- PG_DATABASE=${PG_DATABASE}
depends_on: depends_on:
- db - db
pull_policy: always
db: db:
container_name: illegitimate-postgres container_name: illegitimate-postgres
image: postgres:16.4 image: postgres:16.4
@@ -22,6 +26,6 @@ services:
ports: ports:
- 127.0.0.1:5432:5432 - 127.0.0.1:5432:5432
environment: environment:
- POSTGRES_PASSWORD=${PG_PASSWD} - POSTGRES_PASSWORD=${PG_PASSWORD}
- POSTGRES_USER=${PG_USER} - POSTGRES_USER=${PG_USER}
- POSTGRES_DB=illegitimate - POSTGRES_DB=${PG_DATABASE}

View File

@@ -13,6 +13,7 @@
"homepage": "https://gitlab.com/illegitimate/illegitimate-bot", "homepage": "https://gitlab.com/illegitimate/illegitimate-bot",
"scripts": { "scripts": {
"start": "bun run --bun src/index.ts", "start": "bun run --bun src/index.ts",
"bundle": "bun run scripts/build.ts",
"dev": "bun run --bun --watch src/index.ts", "dev": "bun run --bun --watch src/index.ts",
"fmt": "dprint fmt \"**/*.ts\"", "fmt": "dprint fmt \"**/*.ts\"",
"check": "bun tscheck && bun lint", "check": "bun tscheck && bun lint",

37
scripts/build.ts Normal file
View File

@@ -0,0 +1,37 @@
import fs from "node:fs/promises"
const normalFiles = await Promise.all([
fs.readdir("src/commands"),
fs.readdir("src/commands-contextmenu"),
fs.readdir("src/components/autocomplete"),
fs.readdir("src/components/buttons"),
fs.readdir("src/components/modals"),
fs.readdir("src/events/cron")
])
const eventFiles = (await fs.readdir("src/events", { recursive: true })).filter(f => f.endsWith(".ts"))
const files = [
normalFiles[0].map(f => `src/commands/${f}`),
normalFiles[1].map(f => `src/commands-contextmenu/${f}`),
normalFiles[2].map(f => `src/components/autocomplete/${f}`),
normalFiles[3].map(f => `src/components/buttons/${f}`),
normalFiles[4].map(f => `src/components/modals/${f}`),
normalFiles[5].map(f => `src/events/cron/${f}`),
eventFiles.map(f => `src/events/${f}`)
].flat()
await Bun.build({
entrypoints: ["src/index.ts", ...files],
outdir: "dist",
target: "bun",
splitting: true,
sourcemap: "external",
naming: {
entry: "[dir]/[name].[ext]",
chunk: "chunk/[name]-[hash].[ext]",
asset: "asset/[name]-[hash].[ext]"
},
root: "src",
banner: "process.env.BUILD = 'true'"
})

View File

@@ -8,9 +8,9 @@ import logToChannel from "~/utils/Functions/logtochannel"
import tryCatch from "../Functions/trycatch" import tryCatch from "../Functions/trycatch"
import { log } from "../Logger" import { log } from "../Logger"
export default async function loadAutocompleteEvents(client: Client) { export default async function loadAutocompleteEvents(client: Client, ft: "ts" | "js", folder: "src" | "dist") {
const autocompletePath = path.join(import.meta.dirname, "..", "..", "components", "autocomplete") const autocompletePath = path.join(process.cwd(), folder, "components", "autocomplete")
const autocompleteFiles = fs.readdirSync(autocompletePath).filter(file => file.endsWith(".ts")) const autocompleteFiles = fs.readdirSync(autocompletePath).filter(file => file.endsWith(`.${ft}`))
for (const file of autocompleteFiles) { for (const file of autocompleteFiles) {
const filePath = path.join(autocompletePath, file) const filePath = path.join(autocompletePath, file)

View File

@@ -8,9 +8,9 @@ import logToChannel from "~/utils/Functions/logtochannel"
import tryCatch from "../Functions/trycatch" import tryCatch from "../Functions/trycatch"
import { log } from "../Logger" import { log } from "../Logger"
export default async function loadButtonEvents(client: Client) { export default async function loadButtonEvents(client: Client, ft: "ts" | "js", folder: "src" | "dist") {
const btnPath = path.join(import.meta.dirname, "..", "..", "components", "buttons") const btnPath = path.join(process.cwd(), folder, "components", "buttons")
const btnFiles = fs.readdirSync(btnPath).filter(file => file.endsWith(".ts")) const btnFiles = fs.readdirSync(btnPath).filter(file => file.endsWith(`.${ft}`))
for (const file of btnFiles) { for (const file of btnFiles) {
const filePath = path.join(btnPath, file) const filePath = path.join(btnPath, file)

View File

@@ -8,9 +8,9 @@ import logToChannel from "~/utils/Functions/logtochannel"
import tryCatch from "../Functions/trycatch" import tryCatch from "../Functions/trycatch"
import { log } from "../Logger" import { log } from "../Logger"
export default async function loadSlashCommandsEvents(client: Client) { export default async function loadSlashCommandsEvents(client: Client, ft: "ts" | "js", folder: "src" | "dist") {
const cmdPath = path.join(import.meta.dirname, "..", "..", "commands") const cmdPath = path.join(process.cwd(), folder, "commands")
const cmdFiles = fs.readdirSync(cmdPath).filter(file => file.endsWith(".ts")) const cmdFiles = fs.readdirSync(cmdPath).filter(file => file.endsWith(`.${ft}`))
for (const file of cmdFiles) { for (const file of cmdFiles) {
const filePath = path.join(cmdPath, file) const filePath = path.join(cmdPath, file)

View File

@@ -8,9 +8,9 @@ import logToChannel from "~/utils/Functions/logtochannel"
import tryCatch from "../Functions/trycatch" import tryCatch from "../Functions/trycatch"
import { log } from "../Logger" import { log } from "../Logger"
export default async function loadContextMenuEvents(client: Client) { export default async function loadContextMenuEvents(client: Client, ft: "ts" | "js", folder: "src" | "dist") {
const contextMenuPath = path.join(import.meta.dirname, "..", "..", "commands-contextmenu") const contextMenuPath = path.join(process.cwd(), folder, "commands-contextmenu")
const contextMenuFiles = fs.readdirSync(contextMenuPath).filter(file => file.endsWith(".ts")) const contextMenuFiles = fs.readdirSync(contextMenuPath).filter(file => file.endsWith(`.${ft}`))
for (const file of contextMenuFiles) { for (const file of contextMenuFiles) {
const filePath = path.join(contextMenuPath, file) const filePath = path.join(contextMenuPath, file)

View File

@@ -3,9 +3,9 @@ import fs from "fs"
import path from "path" import path from "path"
import { ICron } from "~/typings" import { ICron } from "~/typings"
export default async function loadCronEvents() { export default async function loadCronEvents(ft: "ts" | "js", folder: "src" | "dist") {
const cronPath = path.join(import.meta.dirname, "..", "..", "events", "cron") const cronPath = path.join(process.cwd(), folder, "events", "cron")
const cronFiles = fs.readdirSync(cronPath).filter(file => file.endsWith(".ts")) const cronFiles = fs.readdirSync(cronPath).filter(file => file.endsWith(`.${ft}`))
for (const file of cronFiles) { for (const file of cronFiles) {
const filePath = path.join(cronPath, file) const filePath = path.join(cronPath, file)

View File

@@ -2,11 +2,11 @@ import fs from "fs"
import path from "path" import path from "path"
import { ExtendedClient as Client } from "~/utils/Client" import { ExtendedClient as Client } from "~/utils/Client"
export default async function loadEvents(client: Client) { export default async function loadEvents(client: Client, ft: "ts" | "js", folder: "src" | "dist") {
const serverDir = path.join(import.meta.dirname, "..", "..", "events", "server") const serverDir = path.join(process.cwd(), folder, "events", "server")
const eventDirs = fs.readdirSync(serverDir) const eventDirs = fs.readdirSync(serverDir)
for (const eventDir of eventDirs) { for (const eventDir of eventDirs) {
const eventFiles = fs.readdirSync(path.join(serverDir, eventDir)).filter(file => file.endsWith(".ts")) const eventFiles = fs.readdirSync(path.join(serverDir, eventDir)).filter(file => file.endsWith(`.${ft}`))
const eventName = eventDir const eventName = eventDir
for (const eventFile of eventFiles) { for (const eventFile of eventFiles) {
const eventPath = path.join(serverDir, eventDir, eventFile) const eventPath = path.join(serverDir, eventDir, eventFile)

View File

@@ -8,12 +8,12 @@ import loadCronEvents from "./cron"
import loadEvents from "./events" import loadEvents from "./events"
import loadModalEvents from "./modal" import loadModalEvents from "./modal"
export default async function loadAllEvents(client: ExtendedClient) { export default async function loadAllEvents(client: ExtendedClient, ft: "js" | "ts", folder: "dist" | "src") {
await loadEvents(client).then(() => log.info("Events loaded")) await loadEvents(client, ft, folder).then(() => log.info("Events loaded"))
await loadButtonEvents(client).then(() => log.info("Button events loaded")) await loadButtonEvents(client, ft, folder).then(() => log.info("Button events loaded"))
await loadSlashCommandsEvents(client).then(() => log.info("Slash commands loaded")) await loadSlashCommandsEvents(client, ft, folder).then(() => log.info("Slash commands loaded"))
await loadContextMenuEvents(client).then(() => log.info("Context menu events loaded")) await loadContextMenuEvents(client, ft, folder).then(() => log.info("Context menu events loaded"))
await loadModalEvents(client).then(() => log.info("Modal events loaded")) await loadModalEvents(client, ft, folder).then(() => log.info("Modal events loaded"))
await loadAutocompleteEvents(client).then(() => log.info("Autocomplete events loaded")) await loadAutocompleteEvents(client, ft, folder).then(() => log.info("Autocomplete events loaded"))
await loadCronEvents().then(() => log.info("Cron events loaded")) await loadCronEvents(ft, folder).then(() => log.info("Cron events loaded"))
} }

View File

@@ -8,9 +8,9 @@ import logToChannel from "~/utils/Functions/logtochannel"
import tryCatch from "../Functions/trycatch" import tryCatch from "../Functions/trycatch"
import { log } from "../Logger" import { log } from "../Logger"
export default async function loadModalEvents(client: Client) { export default async function loadModalEvents(client: Client, ft: "ts" | "js", folder: "src" | "dist") {
const modalPath = path.join(import.meta.dirname, "..", "..", "components", "modals") const modalPath = path.join(process.cwd(), folder, "components", "modals")
const modalFiles = fs.readdirSync(modalPath).filter(file => file.endsWith(".ts")) const modalFiles = fs.readdirSync(modalPath).filter(file => file.endsWith(`.${ft}`))
for (const file of modalFiles) { for (const file of modalFiles) {
const filePath = path.join(modalPath, file) const filePath = path.join(modalPath, file)

View File

@@ -7,9 +7,12 @@ import { log } from "./Logger"
const client = new Client() const client = new Client()
const redis = new RedisClient(env.prod.REDISURI) const redis = new RedisClient(env.prod.REDISURI)
const ft = process.env.BUILD !== "true" ? "ts" : "js"
const folder = process.env.BUILD !== "true" ? "src" : "dist"
class Illegitimate { class Illegitimate {
async start() { async start() {
await loadAllEvents(client) await loadAllEvents(client, ft, folder)
await client.start() await client.start()
await this.databases() await this.databases()
this.loadMethods() this.loadMethods()