npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mc.none.vn/bdfd.js

v1.0.0

Published

BDScript-like functions for Discord.js — build powerful bots with familiar, simple syntax / Các hàm kiểu BDScript cho Discord.js

Readme

bdfd.js

EN: BDScript-like functions for Discord.js — build powerful bots with familiar, simple syntax.
VI: Các hàm kiểu BDScript cho Discord.js — viết bot mạnh mẽ với cú pháp quen thuộc và đơn giản.

npm discord.js


📦 Installation / Cài đặt

npm install bdfd.js
# discord.js is required / discord.js là bắt buộc
npm install discord.js

⚠️ Note: If discord.js is not installed, bdfd.js will throw a detailed error on import.
If your version is lower than v14, it will display a warning.

⚠️ Lưu ý: Nếu chưa cài discord.js, bdfd.js sẽ ném lỗi chi tiết khi import.
Nếu phiên bản thấp hơn v14, sẽ hiện cảnh báo.


🎨 Syntax Highlighting / Highlight cú pháp

Install the recommended VS Code extension for BDScript syntax highlighting inside bdfd template literals: Cài extension VS Code để highlight cú pháp BDScript bên trong bdfd template literal:

# In VS Code — open command palette (Ctrl+Shift+P) → "Extensions: Show Recommended Extensions"
# Hoặc cài trực tiếp:
code --install-extension bierner.comment-tagged-templates

Then use the /* bdscript */ comment tag:
Sau đó dùng comment tag /* bdscript */:

const opts = bdfd /* bdscript */`
  $title[Hello World]
  $description[This is my bot!]
  $color[discord]
`

🚀 Quick Start / Bắt đầu nhanh

const { Client, GatewayIntentBits } = require('discord.js')
const { bdfd, createContext, $random, $time } = require('bdfd.js')

const client = new Client({ intents: [GatewayIntentBits.Guilds] })

client.on('interactionCreate', async interaction => {
  if (!interaction.isChatInputCommand()) return

  // ── Method 1: BDFDContext (recommended for complex commands)
  // ── Cách 1: BDFDContext (khuyến nghị cho lệnh phức tạp)
  if (interaction.commandName === 'profile') {
    const ctx = createContext(interaction)

    ctx.$title(`👤 ${interaction.user.username}`)
       .$description(`Joined: ${$time('DD/MM/YYYY')}`)
       .$color('discord')
       .$thumbnail(interaction.user.displayAvatarURL())
       .$addField('ID', interaction.user.id, true)
       .$addField('Luck', String($random(1, 100)) + '%', true)
       .$addTimestamp()
       .$addButton('Close', 'Danger', 'close_profile')

    await ctx.$reply()
  }

  // ── Method 2: bdfd tagged template (quick embeds)
  // ── Cách 2: bdfd tagged template (embed nhanh)
  if (interaction.commandName === 'hello') {
    const name = interaction.user.username

    await interaction.reply(
      bdfd`$title[👋 Hello ${name}!]
           $description[Welcome to the server]
           $color[green]
           $addTimestamp`
    )
  }

  // ── Method 3: bdfd string (runtime / dynamic)
  // ── Cách 3: bdfd chuỗi (chạy lúc runtime / động)
  if (interaction.commandName === 'script') {
    const script = "$title[Dynamic!]$description[Generated at runtime]$color[purple]"
    await interaction.reply(bdfd(script))
  }
})

client.login('YOUR_TOKEN')

📖 API Reference / Tài liệu API

bdfd — Template tag & string parser

const { bdfd } = require('bdfd.js')

// Tagged template (supports JS interpolation + BDScript)
// VI: Tagged template (hỗ trợ nội suy JS + BDScript)
const opts = bdfd`$title[Hello ${user}!]$color[discord]$addTimestamp`

// String version (runtime/dynamic)
// VI: Dạng chuỗi (runtime/động)
const opts2 = bdfd("$title[Hello!]$description[World]")

// Returns Discord.js message options → pass directly to interaction.reply()
// VI: Trả về message options của Discord.js → truyền thẳng vào interaction.reply()
await interaction.reply(opts)

createContext(interaction) / new BDFDContext(interaction)

const { createContext, BDFDContext } = require('bdfd.js')

const ctx = createContext(interaction)   // sugar factory
// hoặc
const ctx = new BDFDContext(interaction)

// ── Embed methods (chainable / có thể chain)
ctx.$title('My Title')
ctx.$description('Some text here')
ctx.$color('#5865F2')        // hex
ctx.$color('discord')        // named colour / màu có tên
ctx.$image('https://...')
ctx.$thumbnail('https://...')
ctx.$footer('Footer text', 'https://icon-url.png')
ctx.$author('Name', 'https://icon.png', 'https://url.com')
ctx.$addField('Field name', 'Field value', true)  // inline = true
ctx.$addTimestamp()
ctx.$url('https://...')

// ── Message options
ctx.$content('Plain text alongside embed')
ctx.$ephemeral()   // Only invoker sees the reply / Chỉ người dùng lệnh thấy

// ── Components
ctx.$addButton('Click me!', 'Primary', 'my_btn_id')
ctx.$addButton('Link', 'Link', 'https://example.com')
ctx.$addSelectMenu('my_menu', 'Choose an option...')
ctx.$addSelectMenuOption('my_menu', 'Option 1', 'opt1', 'Description here', '🎉')
ctx.$disableComponents()   // disable all buttons/menus

// ── Sending
await ctx.$reply()          // reply to interaction
await ctx.$editReply()      // edit original reply
await ctx.$followUp()       // follow-up (after defer/reply)
await ctx.$defer()          // show "thinking…"
await ctx.$sendMessage('CHANNEL_ID')   // send to specific channel

// ── Moderation
await ctx.$ban('USER_ID', 'Reason here', 7)      // ban + delete 7 days msgs
await ctx.$unban('USER_ID')
await ctx.$kick('USER_ID', 'Reason')
await ctx.$timeout('USER_ID', 60 * 60 * 1000, 'Timeout 1 hour')  // ms
await ctx.$giveRole('USER_ID', 'ROLE_ID')
await ctx.$removeRole('USER_ID', 'ROLE_ID')

// ── Build without sending
const messageOptions = ctx.build()
// → { embeds: [...], components: [...], ephemeral: false, ... }

Standalone Utility Functions / Hàm tiện ích độc lập

const {
  // Math
  $random, $sum, $sub, $multi, $div, $mod,
  $sqrt, $pow, $abs, $ceil, $floor, $round,
  $min, $max, $randomString,

  // Text
  $toUpperCase, $toLowerCase, $length, $trim,
  $replaceText, $slice, $indexOf, $includes,
  $startsWith, $endsWith, $repeat, $reverse, $split,
  $codeBlock, $inlineCode, $bold, $italic, $underline,
  $strikethrough, $spoiler, $regexMatch, $regexReplace,

  // Time
  $time, $timestamp, $unixtimestamp, $parseTime,

  // Discord helpers (async)
  $username, $globalName, $avatar,
  $mention, $roleMention, $channelMention,
  $hasRole, $serverName, $serverID, $memberCount, $serverIcon,
  $ping, $botID, $botName, $botAvatar,
  $channelName, $channelID, $dm, $deleteIn, $checkContains,

  // Logic / Misc
  $if, $c, $stop,
} = require('bdfd.js')

// ── Math examples
$random(1, 100)       // → 42
$sum(10, 20, 30)      // → 60
$round(3.14159, 2)    // → 3.14

// ── Text examples
$toUpperCase('hello')         // → "HELLO"
$bold('important')            // → "**important**"
$codeBlock('console.log(x)', 'js')  // → ```js\n...\n```
$replaceText('aabbcc', 'b', 'X')    // → "aaXXcc"

// ── Time examples
$time()                        // → "12/06/2026 14:30:00"
$time('DD/MM/YYYY')            // → "12/06/2026"
$timestamp(Date.now()/1000, 'R')   // → "<t:1749729000:R>"
$unixtimestamp()               // → 1749729000
$parseTime('1h30m')            // → 5400000 (ms)

// ── Discord helpers (async)
const name    = await $username('123456789', client)
const avatarURL = await $avatar('123456789', client, 512)
const dmMsg   = await $dm(client, '123456789', 'Hello!')
const hasAdmin = await $hasRole('123456789', 'ROLE_ID', guild)

// ── Mentions
$mention('123456789')          // → "<@123456789>"
$roleMention('987654321')      // → "<@&987654321>"
$channelMention('111222333')   // → "<#111222333>"

// ── Logic
$if('5 > 3', 'yes', 'no')     // → "yes"
$if(user.bot, 'is bot', 'not bot')

// $timestamp styles:
// t → 2:30 PM     T → 2:30:00 PM
// d → 06/12/2026  D → June 12, 2026
// f → June 12, 2026 2:30 PM  (default)
// F → Friday, June 12, 2026 2:30 PM
// R → 3 hours ago

Supported Colour Names / Tên màu được hỗ trợ

| Name | Hex | |------|-----| | discord / blurple | #5865F2 | | red | #FF0000 | | blue | #0000FF | | green | #00FF00 | | yellow | #FFFF00 | | purple | #800080 | | orange | #FFA500 | | pink | #FF69B4 | | cyan | #00FFFF | | white | #FFFFFF | | black | #000000 | | invisible | #2F3136 | | greyple | #99AAB5 | | fuchsia | #EB459E |


Functions supported in bdfd() strings / Các hàm được hỗ trợ trong chuỗi bdfd()

| BDScript syntax | JS equivalent | |-----------------|---------------| | $title[text] | ctx.$title(text) | | $description[text] | ctx.$description(text) | | $color[value] | ctx.$color(value) | | $image[url] | ctx.$image(url) | | $thumbnail[url] | ctx.$thumbnail(url) | | $footer[text;icon?] | ctx.$footer(text, icon) | | $author[name;icon?;url?] | ctx.$author(name, icon, url) | | $addField[name;value;inline?] | ctx.$addField(name, value, inline) | | $addTimestamp | ctx.$addTimestamp() | | $content[text] | ctx.$content(text) | | $ephemeral | ctx.$ephemeral() | | $addButton[label;style;id;disabled?;emoji?] | ctx.$addButton(...) | | $sum[a;b;…] | $sum(a, b, ...) | | $random[min;max] | $random(min, max) | | $toUpperCase[text] | $toUpperCase(text) | | $toLowerCase[text] | $toLowerCase(text) | | $mention[id] | $mention(id) | | $c[comment] | no-op | | (and more…) | |


📝 License

MIT