UNPKG

permify

Version:

An enterprise-grade utility for simplified Discord permission management with built-in support for multiple storage backends.

211 lines (153 loc) • 8.94 kB
# šŸ›”ļø Permify A robust, enterprise-grade utility for handling permissions and custom access rules in your `discord.js` bot. This package provides a single, flexible solution for simplifying command logic and ensuring users have the correct access, with support for multiple persistent storage backends. ## ✨ Key Features * **Modular Storage Backends:** Seamlessly integrate with **In-Memory**, **SQLite**, **MySQL**, or **MongoDB** for persistent custom permissions. The storage layer is fully pluggable and easy to extend. * **Intuitive API:** The `checkAndRespond()` method streamlines permission checks, handling denial responses in a single, clean line of code. * **Advanced Custom Permissions:** Easily add or remove custom permissions for specific users and roles, perfect for creating "premium" or staff-only commands. Permissions are stored persistently across bot restarts. * **Extensive Error Handling:** Every critical operation is wrapped in a `try...catch` block with clear console logging to help you debug and maintain your application in production. * **Comprehensive Documentation:** With detailed JSDoc comments and this `README`, the package is easy to use for developers of all skill levels. ----- ## šŸ“¦ Installation To install the core package, run the following command in your project directory: ``` npm install permify ``` For persistent storage, you **must also install the relevant database library**: * **SQLite:** `npm install sqlite3` * **MySQL:** `npm install mysql2` * **MongoDB:** `npm install mongodb` ----- ## šŸ“‚ Project Structure The package is now organized for better clarity and maintenance. ``` permify/ ā”œā”€ā”€ index.js # Main entry point and PermissionsManager class └── lib/ └── storages/ ā”œā”€ā”€ baseStorage.js # Abstract base class for all storage providers ā”œā”€ā”€ inMemoryStorage.js # In-memory storage implementation ā”œā”€ā”€ sqliteStorage.js # SQLite storage implementation ā”œā”€ā”€ mysqlStorage.js # MySQL storage implementation └── mongoStorage.js # MongoDB storage implementation ``` ----- ## šŸš€ Getting Started To begin, you need to import the `PermissionsManager` and initialize it with your chosen storage backend. This should be done once when your bot starts up. ### 1\. In-Memory (Default) This option is perfect for testing or simple bots that do not require permission persistence. ```javascript const { PermissionsManager } = require('permify'); // No storageOptions are needed for In-Memory. const permManager = new PermissionsManager(); // You still need to call initialize() to set up the base provider. await permManager.initialize(); ``` ### 2\. SQLite Ideal for single-process applications, SQLite is a simple, file-based database. ```javascript const { PermissionsManager } = require('permify'); const permManager = new PermissionsManager({ storage: 'sqlite', storageOptions: { // Optional path to your database file. path: './permissions.sqlite' } }); await permManager.initialize(); ``` ### 3\. MySQL Use this for full-fledged relational database support in a multi-process environment. ```javascript const { PermissionsManager } = require('permify'); const permManager = new PermissionsManager({ storage: 'mysql', storageOptions: { host: 'localhost', user: 'root', password: 'your_db_password', database: 'my_bot_db' } }); await permManager.initialize(); ``` ### 4\. MongoDB A great choice for a document-based NoSQL database, often used for its flexibility. ```javascript const { PermissionsManager } = require('permify'); const permManager = new PermissionsManager({ storage: 'mongodb', storageOptions: { uri: 'mongodb://localhost:27017/my_bot_db' } }); await permManager.initialize(); ``` ----- ## šŸ“ Command Examples ### Example 1: Basic Permission Checking Use `checkAndRespond()` to easily check for Discord permissions and send a denial message if the user lacks them. ```javascript // A simple slash command to kick a member if (interaction.commandName === 'kick') { // Define the required permissions using Discord.js's built-in bitfields const requiredPerms = [ PermissionsBitField.Flags.KickMembers, PermissionsBitField.Flags.ViewChannel ]; // The checkAndRespond() method handles the permission check and denial message. const hasPermissions = await permManager.checkAndRespond(interaction, requiredPerms); if (!hasPermissions) { return; // Stop execution if the user doesn't have permissions } // If we reach this point, the member has the required permissions. // Proceed with your command logic here. const memberToKick = interaction.options.getMember('user'); await memberToKick.kick(); await interaction.reply({ content: `Successfully kicked ${memberToKick.user.username}.`, ephemeral: true }); } ``` ### Example 2: Custom "Premium" Command System Create commands that are only accessible to specific users or roles that you manually grant access to. This is perfect for a "premium" feature or a staff-only command. **Step 1: Create a command to grant the custom permission.** This should be an administrative command restricted to bot owners or specific roles. ```javascript if (interaction.commandName === 'grant-premium') { const userToGrant = interaction.options.getUser('user'); await permManager.addCustomPermission('premium-command', userToGrant.id); await interaction.reply({ content: `Successfully granted premium access to ${userToGrant.username}!`, ephemeral: true }); } ``` **Step 2: In your `premium-command` logic, use `hasCustomPermission()` to check for access.** ```javascript if (interaction.commandName === 'premium-command') { const hasPremiumAccess = await permManager.hasCustomPermission(interaction.member, 'premium-command'); if (!hasPremiumAccess) { return interaction.reply({ content: 'This is a premium-only command!', ephemeral: true }); } // Only users with custom permission will reach this point. await interaction.reply({ content: 'Welcome, premium user! This is your special content.', ephemeral: true }); } ``` ----- ## šŸ“š API Reference ### `new PermissionsManager(options)` * **`options.storage`** (string, default: `'inmemory'`): The storage provider to use. Supported values: `'inmemory'`, `'sqlite'`, `'mysql'`, `'mongodb'`. * **`options.storageOptions`** (object, optional): Configuration for the chosen storage. * **`options.ephemeralResponse`** (boolean, default: `true`): Sets the default reply visibility for denial messages. ## šŸ“– Methods | Method | Parameters | Return Type | Description | | :--- | :--- | :--- | :--- | | **`initialize()`** | None | `Promise<void>` | Connects to the configured storage backend. **Must be called before any other methods.** | | **`hasAllPermissions()`** | **member**: `GuildMember`, **permissions**: `PermissionResolvable` | `Promise<boolean>` | Checks if a member has **all** the required Discord permissions. | | **`hasAnyPermission()`** | **member**: `GuildMember`, **permissions**: `PermissionResolvable` | `Promise<boolean>` | Checks if a member has **at least one** of the required Discord permissions. | | **`getMissingPermissions()`** | **member**: `GuildMember`, **requiredPermissions**: `PermissionResolvable` | `Promise<string[]>` | Returns an array of the **permission names** that the member is missing. | | **`checkAndRespond()`** | **interaction**: `Interaction`, **requiredPermissions**: `PermissionResolvable`, **customMessage?**: `string` | `Promise<boolean>` | Checks permissions and responds to the user if they are missing. Returns `false` if permissions are missing. | | **`addCustomPermission()`** | **commandName**: `string`, **entityId**: `string` | `Promise<void>` | Grants a custom permission for a specific **user or role**. | | **`removeCustomPermission()`** | **commandName**: `string`, **entityId**: `string` | `Promise<void>` | Removes a custom permission from a **user or role**. | | **`hasCustomPermission()`** | **member**: `GuildMember`, **commandName**: `string` | `Promise<boolean>` | Checks if a member has a specific **custom permission**. | | **`getCustomPermissionsForCommand()`** | **commandName**: `string` | `Promise<string[]>` | Retrieves all entities (**users/roles**) that have a specific custom permission. | ----- ## šŸ¤ Contributing Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. ----- ## āš–ļø License [MIT](https://choosealicense.com/licenses/mit/)