0.1.0 โข Published 9 months ago
@sparkforge/durin v0.1.0
๐ช Durin
Speak friend and enter: A lightweight TypeScript-based permissions guardian for React applications
Features
- ๐ฏ Simple, lightweight role-based access control
 - ๐ Type-safe permission management
 - โ๏ธ React-first design
 - ๐ชถ Zero dependencies
 - ๐ฆ Tree-shakeable
 - ๐งช Thoroughly tested
 
Installation
npm install durin
# or
yarn add durin
# or
pnpm add durinQuick Start
import { PermissionProvider, Protected, usePermissions } from 'durin';
// Define your roles and permissions
const roles = [
  {
    name: 'admin',
    permissions: ['create:users', 'edit:users', 'delete:users']
  },
  {
    name: 'editor',
    permissions: ['edit:users']
  }
];
// Wrap your app with the provider
function App() {
  const userRoles = ['editor']; // Get this from your auth system
  return (
    <PermissionProvider roles={roles} userRoles={userRoles}>
      <YourApp />
    </PermissionProvider>
  );
}
// Use the Protected component
function UserManagement() {
  return (
    <div>
      <Protected 
        requiredPermission="edit:users"
        fallback={<p>Access denied</p>}
      >
        <EditUserForm />
      </Protected>
    </div>
  );
}
// Or use the hook directly
function AdminPanel() {
  const { hasPermission, hasRole } = usePermissions();
  if (!hasRole('admin')) {
    return <p>Admin access required</p>;
  }
  return <div>Admin Panel Content</div>;
}API Reference
PermissionProvider
The root provider component that manages permissions state.
Props
{
  roles: Array<{
    name: string;
    permissions: string[];
  }>;
  userRoles: string[];
  children: ReactNode;
}Protected
A component wrapper that conditionally renders based on permissions.
Props
{
  requiredPermission?: string;
  requiredRole?: string;
  fallback?: ReactNode;
  children: ReactNode;
}usePermissions
A hook for programmatically checking permissions.
const {
  hasPermission: (permission: string) => boolean,
  hasRole: (role: string) => boolean,
  userRoles: Array<{ name: string; permissions: string[] }>
} = usePermissions();Best Practices
Define Clear Permission Names
- Use colon-separated format: 
resource:action - Example: 
users:create,posts:edit 
- Use colon-separated format: 
 Role Hierarchies
- Keep role structures flat when possible
 - Include all required permissions explicitly
 
Error Handling
- Always provide fallback content
 - Handle loading states appropriately
 
Type Safety
- Define permission and role types
 - Use string literals for better type inference
 
Examples
Nested Permissions
<Protected requiredPermission="users:edit">
  <div>
    <h1>User Settings</h1>
    <Protected requiredPermission="users:delete">
      <DeleteUserButton />
    </Protected>
  </div>
</Protected>Combined Role and Permission Checks
<Protected 
  requiredRole="admin"
  requiredPermission="settings:edit"
>
  <AdminSettings />
</Protected>Dynamic Permissions
function FeatureFlag({ feature, children }) {
  const { hasPermission } = usePermissions();
  return hasPermission(`feature:${feature}`) ? children : null;
}Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
 - Create your feature branch
 - Make your changes
 - Run the tests (
npm test) - Submit a pull request
 
License
MIT ยฉ SparkForge
"Not all those who wander are lost, but some just don't have the right permissions." - Gandalf, probably
0.1.0
9 months ago