@bck-inc/core
v1.0.14
Published
Core utils & classes for BCK projects.
Readme
📦 Installation
npm install @bck-inc/core
# ou
yarn add @bck-inc/coreRequiert Node >= 18 (global fetch, discord.js v14 support).
🚀 Démarrage rapide
const utils = require('@bck-inc/core');
// Attendre 1 seconde
await utils.wait(1000);
// Logger stylé (couleurs §x)
utils.co('§aOK §7Tout roule');
// Capitaliser
console.log(utils.capitalize('bonjour le monde', true)); // 'Bonjour Le Monde'🧰 Utils — Fonctions
Chaque fonction inclut une description et un exemple.
⏳ wait(ms): attend ms puis résout (Promise).
const { wait } = require('@bck-inc/core'); await wait(500);🎨 toStyled(str): rend les codes §x (style Minecraft) en couleurs ANSI console.
const { toStyled } = require('@bck-inc/core'); console.log(toStyled('§4Erreur §rnormal'));🧭 callerLocation(depth?): retourne "fichier:ligne:col" d’où a été loggé.
const { callerLocation } = require('@bck-inc/core'); console.log('Ici:', callerLocation());🗒️ co(text, type?): logger stylé avec info d’appelant (log|warn|debug|error|trace).
const { co } = require('@bck-inc/core'); co('§eInfo', 'log'); co('§cErreur', 'error');💾 savebdd(path?): sauvegarde un JSON au chemin donné (true/false).
const { savebdd } = require('@bck-inc/core'); const ok = await savebdd('./bdd.json');🆔 generateUUID(length?): identifiant hex avec tirets insérés automatiquement.
const { generateUUID } = require('@bck-inc/core'); console.log(await generateUUID(32));🎲 rng(min?, max?): entier aléatoire inclusif.
const { rng } = require('@bck-inc/core'); console.log(await rng(10, 20));✂️ wordsCount(text): compte les mots (split sur espaces).
const { wordsCount } = require('@bck-inc/core'); console.log(await wordsCount('Hello world!')); // 2🧩 getJsonKeys(obj, parentKey?): liste toutes les clés imbriquées ("a.b.c").
const { getJsonKeys } = require('@bck-inc/core'); const keys = await getJsonKeys({ a: { b: 1 } }); // ['a','a.b']🔎 getJsonFilteredKeys(obj, filterKey, includeEmpty?): feuilles sous filterKey.
const { getJsonFilteredKeys } = require('@bck-inc/core'); const leaves = await getJsonFilteredKeys({ a: { b: 1 } }, 'a'); // ['a.b']🧭 getValueFromKeyPath(obj, keyPath): valeur à partir d’un chemin ("a.b.c").
const { getValueFromKeyPath } = require('@bck-inc/core'); console.log(await getValueFromKeyPath({ a:{ b:1 } }, 'a.b')); // 1🔤 capitalize(text, eachWord?): majuscule sur 1er caractère ou chaque mot.
const { capitalize } = require('@bck-inc/core'); console.log(capitalize('bonjour le monde')); // 'Bonjour le monde' console.log(capitalize('bonjour le monde', true)); // 'Bonjour Le Monde'🛡️ Discord helpers (Discord.js requis)
- hasRole(guild, member, roleId)
const { hasRole } = require('@bck-inc/core'); const ok = await hasRole(guild, member, 'ROLE_ID'); - hasPermission(member, permissions)
const { hasPermission } = require('@bck-inc/core'); const can = await hasPermission(member, 'ManageGuild');
- hasRole(guild, member, roleId)
🧱 Classes
📺 Observer — Surveillance YouTube/Twitch
Surveille YouTube et Twitch et émet:
- SVE.youtubeVideo
- SVE.twitchStreamOnline
- SVE.twitchVod
Persistance optionnelle, formatters personnalisés, config par cible.
const { Observer, co } = require('@bck-inc/core');
const obs = new Observer({
ytIntervalMs: 60000,
twIntervalMs: 60000,
twitchClientId: process.env.TWITCH_CLIENT_ID,
twitchClientSecret: process.env.TWITCH_CLIENT_SECRET
});
await obs.addFromUrl('https://www.youtube.com/@handle');
await obs.addFromUrl('https://www.twitch.tv/shroud');
obs.on('SVE.youtubeVideo', (e) => co(`YT: ${e.title} -> ${e.link || ''}`));
obs.on('SVE.twitchStreamOnline', (e) => co(`TW LIVE: ${e.userLogin} -> ${e.title}`));
obs.on('SVE.twitchVod', (e) => co(`TW VOD: ${e.userLogin} -> ${e.title}`));
obs.start();Persistance:
class JsonFileAdapter {
constructor(file) { this.file = file; }
async load() { try { return JSON.parse(require('fs').readFileSync(this.file,'utf8')); } catch { return null; } }
async save(state) { require('fs').writeFileSync(this.file, JSON.stringify(state, null, 2)); }
}
const obs = new Observer({ persistence: new JsonFileAdapter('./observer.json'), autoLoad: true, saveOnChange: true });Formatters et config par cible:
const obs = new Observer({
defaultFormatterKey: 'discordEmbed',
formatters: {
discordEmbed: (event, payload) => ({ embeds: [{ title: payload.title, url: payload.link || payload.url }] })
}
});
obs.setYouTubeConfig('UCxxxxxxxxxxxxxxxxxxxxxx', { formatterKey: 'discordEmbed' });
obs.setTwitchConfig('123456789', { formatterKey: 'discordEmbed' });🛡️ ARC — Anti-Raid Captcha
Anti-raid pour nouveaux membres: challenges boutons, math, ou image-math (Canvas). Hooks, messages, modes personnalisés, persistance adaptable.
import { ARC } from '@bck-inc/core';
const arc = new ARC(client, {
defaults: {
enabled: true,
mode: 'buttons', // 'buttons' | 'math' | 'image-math'
challengeChannelId: null, // null = DM
verifiedRoleId: 'ROLE_VERIFIED',
unverifiedRoleId: 'ROLE_UNVERIFIED',
timeoutMs: 120000,
maxAttempts: 3,
kickOnFail: false,
alertChannelId: 'ALERT_CHANNEL_ID',
raidWindowMs: 60000,
raidJoinThreshold: 6,
},
saveOnChange: true
});
arc.start();Mode image-math (Canvas, peer optionnel):
arc.setGuildConfig('GUILD_ID', { mode: 'image-math' });Personnalisation:
arc.setMessages({ challengeTitle: 'Vérification', successReply: '✅ Bienvenue!' });
arc.setLogger((m)=>console.log(m));
arc.setPersistence({ load: async () => ({ guildConfigs: [] }), save: async () => {} });
arc.registerMode('emoji', async ({ token, djs }) => {
const options = ['😀','😎','😴']; // correct: index 0
const row = new djs.ActionRowBuilder().addComponents(
...options.map((v,i)=> new djs.ButtonBuilder().setCustomId(`arc:${token}:ans:${i}`).setLabel(v).setStyle(djs.ButtonStyle.Secondary))
);
const embed = new djs.EmbedBuilder().setTitle('Choisis 😀');
return { row, embed, correctCustomId: `arc:${token}:ans:0` };
});ℹ️ canvas est un peerDependency optionnel pour le mode image-math.
🎫 TicketManager — Gestion de tickets
Crée salons/threads de support, panneau d’ouverture, limites, staff, transcripts.
import { TicketManager } from '@bck-inc/core';
const tickets = new TicketManager(client, {
defaults: {
enabled: true,
categoryId: 'CATEGORY_ID',
staffRoleIds: ['STAFF_ROLE'],
panelMessage: 'Besoin d’aide ?',
panelButtonLabel: '📩 Ouvrir un ticket',
transcriptChannelId: 'TRANSCRIPT_CH',
useThreads: false,
maxOpenPerUser: 2,
nameTemplate: 'ticket-${user}-${count}',
}
});
tickets.start();
await tickets.createPanel('GUILD_ID', 'CHANNEL_ID');
const t = await tickets.openTicket('GUILD_ID', 'USER_ID', 'Mon problème');
await tickets.claimTicket(t.id, 'STAFF_ID');
await tickets.closeTicket(t.id, 'STAFF_ID', 'Résolu');🎉 GiveawayManager — Giveaways pondérés
Lance des giveaways, participation via bouton, règles (rôles, ancienneté), pondération, reroll.
import { GiveawayManager } from '@bck-inc/core';
const gw = new GiveawayManager(client, {
defaultColor: 0x5865f2,
creatorName: 'BCK',
showAdminButtons: true
});
const g = await gw.startGiveaway({
channelId: 'CHANNEL_ID',
prize: 'Nitro',
durationMs: 10 * 60_000,
winners: 2,
description: 'Clique pour participer',
rules: { allowedRoles: ['ROLE_PARTICIPANT'], extraEntriesByRole: { 'ROLE_VIP': 2 } }
});
await gw.endGiveaway(g.id);
await gw.reroll(g.id, 1);📈 LevelingManager — Système de niveaux
XP sur messages (cooldown, min chars, bonus pièces jointes), rôles récompense, multiplicateurs, annonces.
import { LevelingManager } from '@bck-inc/core';
import { Client } from 'discord.js';
const client = new Client({ intents: [/* ... */] });
const leveling = new LevelingManager(client, {
defaults: {
enabled: true, cooldownMs: 60000, minChars: 5,
baseXp: [5, 15], attachmentBonus: 5,
roleRewards: [{ level: 10, roleId: '1234567890' }],
roleMultipliers: { '1234567890': 1.5 },
announceLevelUp: true,
},
logPrefix: '[Leveling]',
announceTemplate: ({ member, level }) => `Bravo ${member.user.username}, niveau ${level} !`,
});
leveling.start();
await leveling.addXP('guildId', 'userId', 50);
const top = leveling.getLeaderboard('guildId', 10);💰 EconomyManager — Économie simple
Portefeuilles/banque, daily/weekly/work, transferts (taxe), multiplicateurs par rôles, leaderboard.
import { EconomyManager } from '@bck-inc/core';
const eco = new EconomyManager(client, {
defaults: {
currency: '⛃',
startingBalance: 50,
dailyRange: [100, 200],
workRange: [25, 75],
transferTax: 0.05,
roleMultipliers: { 'ROLE_VIP': 1.25 }
}
});
// Récompenses
console.log(await eco.daily('GUILD', 'USER')); // { ok, amount, raw } or cooldown
console.log(await eco.work('GUILD', 'USER'));
// Transfert
console.log(eco.transfer('GUILD', 'FROM_ID', 'TO_ID', 250)); // { sent, received, tax }
// Classement
console.log(eco.leaderboard('GUILD', 'net', 10));⚙️ BCK — Emojis d’application (global app emojis)
Charge les emojis d’application (client.application) et fournit recherche, mention, composant, génération de types (IntelliSense).
import { BCK } from '@bck-inc/core';
const helper = new BCK({ client, autoLoadAppEmojis: true });
// attendre si besoin
await helper.appEmojisEnsureFresh();
console.log(await helper.appEmojiNames());
console.log(await helper.appEmojiMention('my_emoji', '✅'));
console.log(await helper.appEmojiComponent('my_emoji')); // { id,name,animated }
// Générer un fichier typé (union des noms)
await helper.appEmojisGenerateTypes('src/generated/appEmojis.ts');🌐 Variables d’environnement (Twitch)
- TWITCH_CLIENT_ID
- TWITCH_CLIENT_SECRET
Peuvent aussi être passées au constructeur d’Observer.
🪪 Licence
MIT © BCK Team
