Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "module",
"scripts": {
"build": "tsc",
"start": "node --env-file=.env dist/index.js",
"start": "node --env-file=.env .",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
entry=$(node -p "require('./package.json').main || 'index.js'")
case "$entry" in
  *.ts) echo "Package root resolves to TypeScript: $entry"; exit 1 ;;
esac
test -f "$entry" || { echo "Entrypoint missing: $entry"; exit 1; }

Repository: teamboostify/boostify

Length of output: 193


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package.json =="
cat -n package.json | sed -n '1,120p'

echo
echo "== files matching dist/index.js or index.js =="
git ls-files | rg '(^|/)(dist/index\.js|index\.js)$' || true

echo
echo "== prisma-related package versions =="
node - <<'PY'
import json
from pathlib import Path
pkg = json.loads(Path('package.json').read_text())
for section in ('dependencies','devDependencies','peerDependencies','optionalDependencies'):
    for name in ('prisma','`@prisma/client`','`@prisma/adapter-pg`'):
        if name in pkg.get(section, {}):
            print(section, name, pkg[section][name])
PY

Repository: teamboostify/boostify

Length of output: 2075


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path
pkg = json.loads(Path('package.json').read_text())
print(json.dumps({
    "scripts": pkg.get("scripts", {}),
    "main": pkg.get("main"),
    "dependencies": {k: v for k, v in pkg.get("dependencies", {}).items() if k in ("prisma", "`@prisma/client`", "`@prisma/adapter-pg`")},
    "devDependencies": {k: v for k, v in pkg.get("devDependencies", {}).items() if k in ("prisma", "`@prisma/client`", "`@prisma/adapter-pg`")},
}, indent=2))
PY

echo
echo "Tracked entrypoint files:"
git ls-files | rg '(^|/)(dist/index\.js|index\.js|src/index\.(js|ts))$' || true

Repository: teamboostify/boostify

Length of output: 539


Build before start start resolves to dist/index.js, but the repo doesn’t provide that file on a clean checkout. Add a prestart build step or make start run npm run build first.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 9, Update the package.json start script so it builds
the project before launching the entrypoint that resolves to dist/index.js,
using a prestart script or an equivalent build-first command. Ensure a clean
checkout can run npm start successfully.

"dev": "tsx --env-file=.env src/index.ts",
"prisma:generate": "prisma generate"
},
Expand All @@ -20,8 +20,8 @@
"typescript": "^7.0.2"
},
"dependencies": {
"@prisma/adapter-pg": "^7.8.0",
"@prisma/client": "^7.8.0",
"@prisma/adapter-pg": "^7.9.0",
"@prisma/client": "^7.9.0",
"axios": "^1.16.0",
"chalk": "^4.1.2",
"discord.js": "^14.27.0",
Expand Down
34 changes: 34 additions & 0 deletions src/base/functions/color-resolve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ColorResolvable } from "discord.js";
import { client } from "../../index.js";
import { SystemColors } from "../../libs/colors.js";
import { logger } from "../../libs/logger.js";

const cachedColors = new Map<string, ColorResolvable>();

export async function resolveColor(): Promise<ColorResolvable> {
if (process.env.CLIENT_ID == '1453802179789066442') return SystemColors.main; // custom branding coming as a future update

const guildid = process.env.GUILD_ID! || process.env.MASTER_GUILD!;

if (!guildid) {
return SystemColors.main;
}

if (cachedColors.has(guildid)) {
return cachedColors.get(guildid)!;
}
Comment thread
breadddevv marked this conversation as resolved.

try {
const guild = await client.guilds.fetch(guildid);
const me = await guild.members.fetchMe();

const color = me.displayColor;
const resolved: ColorResolvable = color !== 0 ? color : SystemColors.main;

cachedColors.set(guildid, resolved);
return resolved;
} catch (err) {
logger.error(`Failed to resolve color for guild ${guildid}: ${err}`);
return SystemColors.main;
}
}
15 changes: 15 additions & 0 deletions src/base/functions/embed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { EmbedBuilder, ColorResolvable, ContainerBuilder, resolveColor as resolveColorValue } from "discord.js";
import { resolveColor } from "./color-resolve.js";

export async function Embed(color?: ColorResolvable): Promise<EmbedBuilder> {
const embedColor = color ?? await resolveColor();

return new EmbedBuilder().setColor(embedColor);
}

export async function Container(color?: ColorResolvable): Promise<ContainerBuilder> {
const embedColor = color ?? await resolveColor();
const accentColor = resolveColorValue(embedColor);

return new ContainerBuilder().setAccentColor(accentColor);
}
30 changes: 14 additions & 16 deletions src/commands/booster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
SeparatorSpacingSize,
ButtonBuilder,
ButtonStyle,
Colors,
} from "discord.js";
import {
getBooster,
Expand All @@ -21,6 +22,7 @@ import {
} from "../services/boosterService.js";
import { Command } from "../base/classes/command.js";
import { logger } from "../libs/logger.js";
import { Container, Embed } from "../base/functions/embed.js";

export default new Command({
info: new SlashCommandBuilder()
Expand Down Expand Up @@ -106,9 +108,8 @@ export default new Command({
if (!result.data) {
if (isBoostingServer && member && member.premiumSince) {
const discordBoost = `🟢 Boosting since <t:${Math.floor(member.premiumSince.getTime() / 1000)}:D>`;
const embed = new EmbedBuilder()
.setColor(0xff73fa)
.setTitle(`Here is the Booster Information for ${user.id}!`)
const embed = await Embed();
embed.setTitle(`Here is the Booster Information for ${user.id}!`)
.setThumbnail(avatarUrl)
.addFields(
{
Expand All @@ -126,8 +127,8 @@ export default new Command({
return;
}

const container = new ContainerBuilder()
.setAccentColor(0xe642a4)
const container = await Container();
container.setAccentColor(0xe642a4)
.addTextDisplayComponents(
new TextDisplayBuilder().setContent("**Uh oh!**"),
new TextDisplayBuilder().setContent(
Expand Down Expand Up @@ -157,9 +158,8 @@ export default new Command({
.setLabel("Our Support Server")
.setURL("https://discord.gg/NUtyKs7hA6");

const container = new ContainerBuilder()
.setAccentColor(0xe642a4)
.addTextDisplayComponents(
const container = await Container(Colors.Red)
container.addTextDisplayComponents(
new TextDisplayBuilder().setContent("**Uh oh!**"),
new TextDisplayBuilder().setContent(
`It looks like we ran into an issue\n-# If this issue is persistent, please consult your console logs if you're using a self-hosted version of Boostify, and create an issue on our [Repository](https://github.com/teamboostify/boostify/issues), or use our support server!.`,
Expand All @@ -184,8 +184,8 @@ export default new Command({
const isActiveBooster =
booster.active && booster.boostCounts > 0 && !!premiumSince;

const embed = new EmbedBuilder()
.setColor(booster.active ? 0xf47fff : 0x99aab5)
const embed = await Embed();
embed.setColor(booster.active ? 0xf47fff : 0x99aab5)
.setTitle(`Booster Info: ${user.username}`)
.setThumbnail(avatarUrl)
.addFields(
Expand Down Expand Up @@ -253,9 +253,8 @@ export default new Command({
}

const boostWord = amount === 1 ? "boost" : "boosts";
const container = new ContainerBuilder()
.setAccentColor(0xe642a4)
.addTextDisplayComponents(
const container = await Container();
container.addTextDisplayComponents(
new TextDisplayBuilder().setContent(`**Boost successfully added!**`),
new TextDisplayBuilder().setContent(
`We've successfully added ${amount} ${boostWord} to ${user}'s profile.`,
Expand Down Expand Up @@ -294,9 +293,8 @@ export default new Command({
getTotalBoosts(discordGuild.id),
]);

const embed = new EmbedBuilder()
.setColor(0xf47fff)
.setTitle("Server Boost Statistics")
const embed = await Embed();
embed.setTitle("Server Boost Statistics")
.addFields(
{
name: "Current Boosters",
Expand Down
10 changes: 5 additions & 5 deletions src/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "discord.js";
import { Command } from "../base/classes/command.js";
import { SystemColors } from "../libs/colors.js";
import { Container } from "../base/functions/embed.js";

const knowledgebase: Record<string, string> = {
booster:
Expand Down Expand Up @@ -574,17 +575,16 @@ export default new Command({
const sub = interaction.options.getString("command", true);

if (knowledgebase[sub]) {
const container = new ContainerBuilder()
.setAccentColor(SystemColors.main)
.addTextDisplayComponents(txt => txt.setContent(
const container = await Container()
container.addTextDisplayComponents(txt => txt.setContent(
`## Command info: \`/${sub}\`\n`+
knowledgebase[sub]
));

await interaction.reply({ components: [container], flags: [MessageFlags.IsComponentsV2]})
} else {
const container = new ContainerBuilder()
.setAccentColor(Colors.Red)
const container = await Container(Colors.Red);
container.setAccentColor(Colors.Red)
.addTextDisplayComponents(txt => txt.setContent(
`## Command not found\n`+
`We couldn't find any resources matching the command \`${sub}\`, please try later.`
Expand Down
8 changes: 4 additions & 4 deletions src/commands/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import axios from "axios";
import { Command } from "../base/classes/command.js";
import packageInfo from "../../package.json" with { type: "json" };
import { Embed } from "../base/functions/embed.js";

interface GithubRes {
login: string,
Expand All @@ -33,16 +34,15 @@ export default new Command({

const uptimeString = `${days}d ${hours}h ${minutes}m ${seconds}s`;

const embed = new EmbedBuilder()
.setColor(16712630)
.setThumbnail(interaction.client.user.displayAvatarURL({ size: 2048 }))
const embed = await Embed();
embed.setThumbnail(interaction.client.user.displayAvatarURL({ size: 2048 }))
.setTitle("Bot information")
.setDescription(
"Boostify is a Discord bot designed to help you manage your server boosts."
)
.addFields(
{
name: "Developers",
name: `Contributors [${info.data.length}]`,
value: info.data
.map((user) => `[@${user.login}](${user.html_url})`)
.join("\n"),
Expand Down
Loading
Loading