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

logique-permission

v1.0.1

Published

Role-Based Access Control (RBAC) package for Node.js

Downloads

3

Readme

Logique Permission

A powerful Role-Based Access Control (RBAC) package for Node.js. This package provides a flexible and extensible permission system with dependency injection support.

Features

  • 🎯 Role-Based Access Control - Manage roles and permissions easily
  • 🔧 Dependency Injection - Flexible architecture with DI container
  • 🗄️ Multiple Storage Backends - In-memory, database, or custom storage
  • 🛡️ Multiple Guards - Support for web, API, and custom guards
  • 📦 TypeScript Support - Full type definitions and IntelliSense
  • 🧪 Comprehensive Testing - 38+ test cases with Jest
  • 🚀 Production Ready - MIT licensed and well documented

Installation

npm install logique-permission

Quick Start

Basic Usage

import { 
  PermissionManager, 
  Permission, 
  Role, 
  createPermission, 
  createRole 
} from 'logique-permission';

// Create permissions
const editUsersPermission = createPermission('edit-users');
const deleteUsersPermission = createPermission('delete-users');

// Create roles
const adminRole = createRole('admin');
const moderatorRole = createRole('moderator');

// Assign permissions to roles
adminRole.addPermission(editUsersPermission);
adminRole.addPermission(deleteUsersPermission);
moderatorRole.addPermission(editUsersPermission);

// Create user with permissions
const user = {
  id: '1',
  name: 'John Doe',
  email: '[email protected]',
  roles: [adminRole],
  permissions: []
};

// Add permission methods to user
Object.assign(user, {
  hasPermission(permission: string | Permission, guardName: string = 'web'): boolean {
    const permissionName = typeof permission === 'string' ? permission : permission.name;
    
    // Check direct permissions
    if (this.permissions?.some((p: Permission) => p.name === permissionName)) {
      return true;
    }

    // Check permissions through roles
    return this.roles?.some((role: Role) => 
      role.permissions?.some((p: Permission) => p.name === permissionName)
    ) || false;
  },

  hasRole(role: string | Role, guardName: string = 'web'): boolean {
    const roleName = typeof role === 'string' ? role : role.name;
    return this.roles?.some((r: Role) => r.name === roleName) || false;
  }
});

// Check permissions
console.log(user.hasPermission('edit-users')); // true
console.log(user.hasPermission('delete-users')); // true
console.log(user.hasRole('admin')); // true

Using PermissionManager

const manager = new PermissionManager({
  defaultGuard: 'web',
  cacheEnabled: true,
  cacheTtl: 3600
});

// Create permissions and roles
const permission = manager.createPermission('api-access', 'api');
const role = manager.createRole('api-user', 'api');

// Check permissions
const hasPermission = manager.checkPermission(user, 'edit-users');
const hasRole = manager.checkRole(user, 'admin');

Package Structure

logique-permission/
├── src/
│   ├── types/
│   │   └── index.ts                    # TypeScript interfaces and types
│   ├── models/
│   │   ├── Permission.ts               # Permission model class
│   │   └── Role.ts                     # Role model class
│   ├── guards/
│   │   └── Guard.ts                    # Guard system for multiple contexts
│   ├── traits/
│   │   ├── HasPermissions.ts           # Trait for permission functionality
│   │   └── HasRoles.ts                 # Trait for role functionality
│   ├── exceptions/
│   │   └── PermissionException.ts      # Custom exception classes
│   ├── container/
│   │   └── Container.ts                # Dependency injection container
│   ├── providers/
│   │   └── PermissionServiceProvider.ts # Default service provider
│   ├── interfaces/
│   │   └── Repository.ts               # Repository pattern interfaces
│   ├── PermissionManager.ts            # Main permission manager class
│   └── index.ts                        # Package entry point and exports
├── dist/                               # Compiled JavaScript output
├── examples/
│   ├── basic-usage.ts                  # Basic usage examples
│   └── dependency-injection.ts         # DI usage examples
├── src/__tests__/                      # Test files
├── package.json                        # Package configuration
├── tsconfig.json                       # TypeScript configuration
├── jest.config.js                      # Jest testing configuration
├── .eslintrc.js                        # ESLint configuration
├── README.md                           # This documentation
├── LICENSE                             # MIT License
├── CHANGELOG.md                        # Version history
└── .npmignore                          # Files excluded from npm package

File Descriptions

Core Classes

  • PermissionManager.ts - Main class that orchestrates the entire permission system
  • Permission.ts - Represents a single permission with metadata
  • Role.ts - Represents a role that can have multiple permissions
  • Guard.ts - Manages permissions and roles for different contexts (web, API, etc.)

Traits (Reusable Components)

  • HasPermissions.ts - Adds permission checking methods to any class
  • HasRoles.ts - Adds role checking methods to any class

Dependency Injection

  • Container.ts - Simple DI container for service management
  • PermissionServiceProvider.ts - Default service registration
  • Repository.ts - Interfaces for different storage backends

Types and Exceptions

  • types/index.ts - TypeScript interfaces and type definitions
  • PermissionException.ts - Custom exception classes for error handling

Dependency Injection

This package supports dependency injection for easy testing and customization:

Basic DI Usage

import { 
  Container, 
  PermissionServiceProvider, 
  PermissionManager 
} from 'logique-permission';

// Setup container
const container = new Container();
container.register(new PermissionServiceProvider());
await container.boot();

// Resolve PermissionManager
const manager = container.resolve<PermissionManager>('permission.manager');

Custom Dependencies

// Register custom cache service
container.singleton('cache.service', () => new RedisCacheService());

// Register custom repository
container.singleton('permission.repository', () => new DatabasePermissionRepository());

// Create manager with custom dependencies
const manager = new PermissionManager(config, {
  cacheService: customCache,
  permissionRepository: customRepo
});

Service Providers

class CustomPermissionServiceProvider implements ServiceProvider {
  register(container: Container): void {
    // Register custom services
    container.singleton('custom.service', () => new CustomService());
  }

  async boot(container: Container): Promise<void> {
    // Boot-time initialization
    console.log('Custom services initialized');
  }
}

container.register(new CustomPermissionServiceProvider());

Multiple Guards

You can use different guards for different contexts:

// Create permissions for different guards
const webPermission = createPermission('web-access', 'web');
const apiPermission = createPermission('api-access', 'api');

// Check permissions with specific guards
console.log(user.hasPermission('web-access', 'web')); // true
console.log(user.hasPermission('api-access', 'api')); // false

Custom Permission Checks

Register custom logic for permission and role checking:

const manager = new PermissionManager();

// Register custom permission check
manager.registerPermissionCheck('custom', (user, permission, guardName) => {
  // Custom logic for permission checking
  return user.someCustomCheck(permission);
});

// Register custom role check
manager.registerRoleCheck('custom', (user, role, guardName) => {
  // Custom logic for role checking
  return user.someCustomRoleCheck(role);
});

Using Traits

Add permission and role functionality to your classes:

import { HasPermissionsTrait, HasRolesTrait } from 'logique-permission';

class User {
  private permissionsTrait = new HasPermissionsTrait();
  private rolesTrait = new HasRolesTrait();

  constructor(public id: string, public name: string) {}

  // Delegate permission methods
  hasPermission(permission: string | Permission, guardName?: string): boolean {
    return this.permissionsTrait.hasPermission(permission, guardName);
  }

  hasRole(role: string | Role, guardName?: string): boolean {
    return this.rolesTrait.hasRole(role, guardName);
  }

  // Add more methods as needed
  givePermissionTo(permission: string | Permission, guardName?: string): void {
    this.permissionsTrait.givePermissionTo(permission, guardName);
  }

  assignRole(role: string | Role, guardName?: string): void {
    this.rolesTrait.assignRole(role, guardName);
  }
}

API Reference

PermissionManager

Constructor

new PermissionManager(
  config?: PermissionManagerConfig, 
  dependencies?: PermissionManagerDependencies
)

Methods

  • createGuard(name: string): Guard
  • getGuard(name: string): Guard
  • createPermission(name: string, guardName?: string): Permission
  • createRole(name: string, guardName?: string): Role
  • checkPermission(user: PermissionUser, permission: string | Permission, guardName?: string): boolean
  • checkRole(user: PermissionUser, role: string | Role, guardName?: string): boolean
  • savePermissionToRepository(permission: Permission): Promise<void>
  • saveRoleToRepository(role: Role): Promise<void>
  • saveGuardToRepository(guard: Guard): Promise<void>
  • dispatchEvent(event: string, data: any): Promise<void>

Permission

Constructor

new Permission(data: Partial<Permission>)

Methods

  • equals(other: Permission): boolean
  • toJSON(): Permission

Role

Constructor

new Role(data: Partial<Role>)

Methods

  • addPermission(permission: Permission | IPermission): void
  • removePermission(permission: Permission | IPermission): void
  • hasPermission(permission: Permission | IPermission): boolean
  • syncPermissions(permissions: (Permission | IPermission)[]): void
  • equals(other: Role): boolean
  • toJSON(): Role

HasPermissionsTrait

Methods

  • hasPermission(permission: string | Permission, guardName?: string): boolean
  • hasAnyPermission(permissions: (string | Permission)[], guardName?: string): boolean
  • hasAllPermissions(permissions: (string | Permission)[], guardName?: string): boolean
  • givePermissionTo(permission: string | Permission, guardName?: string): void
  • revokePermissionTo(permission: string | Permission, guardName?: string): void
  • syncPermissions(permissions: (string | Permission)[], guardName?: string): void

HasRolesTrait

Methods

  • hasRole(role: string | Role, guardName?: string): boolean
  • hasAnyRole(roles: (string | Role)[], guardName?: string): boolean
  • hasAllRoles(roles: (string | Role)[], guardName?: string): boolean
  • assignRole(role: string | Role, guardName?: string): void
  • removeRole(role: string | Role, guardName?: string): void
  • syncRoles(roles: (string | Role)[], guardName?: string): void

Dependency Injection

Container

class Container {
  bind<T>(abstract: string, concrete: T | (() => T)): void
  singleton<T>(abstract: string, concrete: T | (() => T)): void
  resolve<T>(abstract: string): T
  has(abstract: string): boolean
  register(provider: ServiceProvider): void
  boot(): Promise<void>
  clear(): void
}

ServiceProvider

interface ServiceProvider {
  register(container: Container): void
  boot?(container: Container): Promise<void>
}

Repository Interfaces

interface PermissionRepository {
  savePermission(permission: Permission): Promise<void>
  findPermission(name: string, guardName?: string): Promise<Permission | null>
  findAllPermissions(guardName?: string): Promise<Permission[]>
  deletePermission(name: string, guardName?: string): Promise<void>
}

interface RoleRepository {
  saveRole(role: Role): Promise<void>
  findRole(name: string, guardName?: string): Promise<Role | null>
  findAllRoles(guardName?: string): Promise<Role[]>
  deleteRole(name: string, guardName?: string): Promise<void>
}

interface CacheService {
  get<T>(key: string): Promise<T | null>
  set<T>(key: string, value: T, ttl?: number): Promise<void>
  delete(key: string): Promise<void>
  clear(): Promise<void>
}

Exception Handling

import { 
  PermissionException, 
  RoleNotFoundException, 
  PermissionNotFoundException, 
  GuardNotFoundException 
} from 'logique-permission';

try {
  const role = manager.getRole('non-existent-role');
} catch (error) {
  if (error instanceof RoleNotFoundException) {
    console.log('Role not found');
  }
}

Storage Options

In-Memory (Default)

  • Fastest performance
  • Data lost on restart
  • Perfect for testing and development

Database Integration

PostgreSQL Example

Complete PostgreSQL integration example is available in examples/database/:

import { Pool } from 'pg';
import { Container, PermissionManager } from 'logique-permission';

// Initialize PostgreSQL connection
const pool = new Pool({
  user: 'postgres',
  host: 'localhost',
  database: 'logique_permission',
  password: 'your_password',
  port: 5432,
});

// Setup DI container with PostgreSQL repositories
const container = new Container();
container.singleton('permission.repository', () => new PostgreSQLPermissionRepository(pool));
container.singleton('role.repository', () => new PostgreSQLRoleRepository(pool));

// Create PermissionManager with database dependencies
const manager = new PermissionManager(config, {
  permissionRepository: container.resolve('permission.repository'),
  roleRepository: container.resolve('role.repository')
});

// Save to database
await manager.savePermissionToRepository(permission);
await manager.saveRoleToRepository(role);

Custom Database Implementation

// Implement custom repository
class DatabasePermissionRepository implements PermissionRepository {
  async savePermission(permission: Permission): Promise<void> {
    // Save to database
  }
  
  async findPermission(name: string, guardName?: string): Promise<Permission | null> {
    // Query from database
  }
}

// Use with DI
container.singleton('permission.repository', () => new DatabasePermissionRepository());

Redis Cache

class RedisCacheService implements CacheService {
  async get<T>(key: string): Promise<T | null> {
    // Get from Redis
  }
  
  async set<T>(key: string, value: T, ttl?: number): Promise<void> {
    // Set to Redis
  }
}

Testing

npm test

Run tests in watch mode:

npm run test:watch

Development

Build the package:

npm run build

Run linting:

npm run lint
npm run lint:fix

Examples

Check the examples/ directory for complete usage examples:

Basic Examples

  • basic-usage.ts - Basic permission and role management
  • dependency-injection.ts - DI container usage

Database Integration

  • database/postgresql-integration.ts - Complete PostgreSQL integration
  • database/migration.sql - Database schema and migrations
  • database/package.json - PostgreSQL dependencies
  • database/README.md - Detailed PostgreSQL setup guide

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - see the LICENSE file for details.