Permix

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 validated when they are created, ensuring your permission definitions are correct before runtime.

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 throw an error
const  = .({
  : {
    edit: true
Object literal may only specify known properties, and 'edit' does not exist in type '{ create: boolean | ((data: unknown) => boolean); }'.
} })

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
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 PermixRules type. This is useful when you want to organize your permission logic in separate files:

import type {  } from 'permix'
import {  } from 'permix'
 
// Define your Permix definition type
type  = {
  : {
    : { : string; : string }
    : 'create' | 'read' | 'update' | 'delete'
  }
}
 
// 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

On this page