Setup
Learn how to setup permissions in your project
Overview
After creating Permix instance, you need to define permissions with setup
method. You can call setup
in any time with any permissions and Permix will replace the previous permissions.
You always should describe all permissions in the setup
method that was defined in the Permix generic type.
For role separation, you can use the template
method.
Object definition
const permix = createPermix<{
post: {
action: 'create'
}
comment: {
action: 'create' | 'update'
}
}>()
permix.setup({
post: {
create: true,
},
comment: {
create: true,
update: true,
}
})
You can also use enum
based permissions. See Enum-based for more information.
Initial
You can set up initial rules directly when creating a Permix instance by passing them as the first parameter to createPermix
.
import { createPermix } from 'permix'
const permix = createPermix<{
post: {
action: 'create' | 'read'
}
comment: {
action: 'create' | 'read' | 'update'
}
}>({
post: {
create: true,
read: true,
},
comment: {
create: false,
read: true,
update: true,
},
})
// The instance is immediately ready to use
permix.check('post', 'create') // true
permix.isReady() // true
When using initial rules, the Permix instance is immediately ready to use without calling setup
first.
Type-Based
When creating a Permix instance, you can define entities that will be used in the setup
method for each related entity. This allows you to check permissions for specific data entities. So instead of boolean
you can use functions to check permissions.
import { createPermix } from 'permix'
interface Post {
id: string
authorId: string
}
const permix = createPermix<{
post: {
dataType: Post
action: 'update'
}
comment: {
action: 'update'
}
}>()
permix.setup({
post: {
update: post => post.- authorId
- id
}
comment: {
update: comment => c }
})
Required
By default dataType
providing optional type to callbacks but you can make it required by adding dataRequired: true
.
import { createPermix } from 'permix'
interface Post {
id: string
authorId: string
}
interface Comment {
id: string
postId: string
}
const = createPermix<{
post: {
dataType: Post
dataRequired: true
action: 'update'
}
comment: {
dataType: Comment
action: 'update'
}
}>()
permix.setup({
post: {
update: post => !!post.authorId }
comment: {
update: comment => !!comment.postId }
})
unknown
If you cannot define entity types in the Permix instance, the types will be unknown
by default, but you can still define them later in the setup
method.
This approach is not recommended as it reduces type safety and IDE support.
import { createPermix } from 'permix'
const permix = createPermix<{
comment: {
action: 'update'
}
}>()
permix.setup({
comment: {
update: (comment: { authorId: string }) => comment.authorId === user.id
}
})
Dynamic
You can use async functions to fetch permissions from external sources and then set them up.
See the template for more examples and patterns.
import { createPermix } from 'permix'
const permix = createPermix<{
post: {
action: 'create' | 'read' | 'update' | 'delete'
}
comment: {
action: 'create' | 'read' | 'update' | 'delete'
}
}>()
// Fetch permissions from API
async function loadUserPermissions(userId: string) {
const permissions = await getPermissionsFromAnyPlace()
permix.setup({
post: {
create: permissions.includes('post:create'),
read: permissions.includes('post:read'),
update: permissions.includes('post:update'),
delete: permissions.includes('post:delete'),
},
comment: {
create: permissions.includes('comment:create'),
read: permissions.includes('comment:read'),
update: permissions.includes('comment:update'),
delete: permissions.includes('comment:delete'),
},
})
}
// Usage
await loadUserPermissions('user-123')
Getting Rules
You can get the current rules from an existing Permix instance using the getRules
function:
import { getRules } from 'permix'
// Get current rules
const rules = getRules(permix)
The getRules
function returns the exact rules object that was set using setup
, including any permission functions.