Traits
Subject models gain role and permission behaviour through mixin functions. This mirrors Spatie's HasRoles and HasPermissions traits, but implemented with JavaScript's prototype chain.
Authorizable
The most common entry point is the Authorizable(BaseClass) function. It composes HasRoles and HasPermissions into a fresh subclass.
import { BaseModel } from '@admicaa/netpress';
import { Authorizable } from '@admicaa/netpress-permissions';
class User extends Authorizable(BaseModel) {
static table = 'users';
}
User now has roles(), permissions(), assignRole(), can(), and all the helpers documented in Roles and Permissions.
Applying To An Existing Class
If you can't extend a wrapping class (for example, the class already extends something custom), use applyAuthorizable to splice the behaviour onto an existing prototype:
import { applyAuthorizable } from '@admicaa/netpress-permissions';
class Admin extends BaseModel {
static table = 'admins';
}
applyAuthorizable(Admin);
applyAuthorizable copies the descriptors from both HasRoles and HasPermissions onto the class prototype. You can call it as many times as you like — duplicate descriptors are overwritten without error.
Splitting The Traits
If you only need roles or only need direct permissions, import each mixin individually:
import { HasRoles, HasPermissions } from '@admicaa/netpress-permissions';
class User extends HasRoles(BaseModel) { /* ... */ }
class ApiClient extends HasPermissions(BaseModel) { /* ... */ }
Note that user.hasPermissionTo('x') will always short-circuit through the role chain. If you apply HasPermissions without HasRoles, the package gracefully reports an empty role list.
Methods Added By HasRoles
roles()relationgetRoles(),getRoleNames()assignRole(...roles),removeRole(...roles),syncRoles(...roles)hasRole(role),hasAnyRole(...roles),hasAllRoles(...roles)
Methods Added By HasPermissions
permissions()relationgetDirectPermissions(),getPermissionsViaRoles(),getAllPermissions()givePermissionTo(...permissions),revokePermissionTo(...permissions),syncPermissions(...permissions)hasDirectPermission(permission),hasPermissionTo(permission)hasAnyPermission(...permissions),hasAllPermissions(...permissions)can(ability, resource = null, options = {})andcannot(...)
can delegates to NetPress core authorization so registered policies and permission-aware models are honoured automatically.
Morph Map
To support inverse queries (Permission.holders(User), Role.assignees(Admin)), register your subject classes with the morph map once at boot:
import { BaseModel } from '@admicaa/netpress';
BaseModel.registerMorphMap({
user: User,
admin: Admin,
});
The Authorizable mixins use morphToMany and morphedByMany, so the registry is required before you run any pivot queries against the package tables. Without it the package cannot resolve polymorphic identifiers.