Template
Learn how to define permissions using templates
Overview
Permix provides a template method that allows you to define permissions in a separate location from where they are set up. This is useful for organizing permission definitions and reusing them across different parts of your application.
Templates are type-checked at compile time, ensuring your permission definitions match the instance definition.
Basic Usage
The simplest way to use templates is to define static permissions:
const adminPermissions = permix.template({
post: {
create: true,
read: true
}
})
// Later, use the template to setup permissions
permix.setup(adminPermissions())Dynamic Templates
Templates can accept parameters to create dynamic permissions based on runtime values:
interface User {
id: string
role: string
}
const userPermissions = permix.template(({ id: userId }: User) => ({
post: {
create: true,
read: true,
update: post => post?.authorId === userId
}
}))
// Use with specific user data
const user = await getUser()
permix.setup(userPermissions(user))Type Safety
Templates maintain full type safety from your Permix instance definition:
import { } from 'permix'
const = <{
: ['create']
}>()
// This will cause a TypeScript error
const = .({
: {
edit: true }
})Role-Based Example
Templates are particularly useful for role-based permission systems:
const editorPermissions = permix.template({
post: {
create: true,
read: true,
update: post => !post?.published,
delete: post => !post?.published
}
})
const userPermissions = permix.template(({ id: userId }: User) => ({
post: {
create: false,
read: true,
update: post => post?.authorId === userId,
delete: false
}
}))
// Setup based on user role
async function setupPermissions() {
const user = await getUser()
const permissionsMap = {
editor: () => editorPermissions(),
user: () => userPermissions(user)
}
return permix.setup(permissionsMap[user.role]())
}Standalone Templates
You can define permission templates outside of the Permix instance using the Rules type. This is useful when you want to organize your permission logic in separate files:
import type { } from 'permix'
import { } from 'permix'
type = {
: [
{ : 'create', : { : string; : string } },
{ : 'read', : { : string; : string } },
{ : 'update', : { : string; : string } },
{ : 'delete', : { : string; : string } },
]
}
// It can be in separate file and imported here
const = <>()
// Create a standalone template function
function (: string, : 'admin' | 'user'): <> {
return {
: {
: === 'admin',
: true,
: === 'admin' ? true : () => ?. === ,
: === 'admin'
}
}
}
// Later, use it with your Permix instance
const = ('1', 'admin')
.()This approach allows you to:
- Keep permission logic separate from your Permix instance
- Reuse permission templates across different parts of your application
- Maintain full type safety with your Permix definition