Skip to content

Macro

Macro allows us to define a custom field to the hook.

Macro v2

Macro v2 use an object syntax with return lifecycle like inline hook.

Elysia.macro allows us to compose custom heavy logic into a simple configuration available in hook, and guard with full type safety.

typescript
import { 
Elysia
} from 'elysia'
const
plugin
= new
Elysia
({
name
: 'plugin' })
.
macro
({
hi
(
word
: string) {
return {
beforeHandle
() {
console
.
log
(
word
)
} } } }) const
app
= new
Elysia
()
.
use
(
plugin
)
.
get
('/', () => 'hi', {
hi
: 'Elysia'
})

Accessing the path should log "Elysia" as the results.

API

macro has the same API as hook.

In previous example, we create a hi macro accepting a string.

We then assigned hi to "Elysia", the value was then sent back to the hi function, and then the function added a new event to beforeHandle stack.

Which is an equivalent of pushing function to beforeHandle as the following:

typescript
import { Elysia } from 'elysia'

const app = new Elysia()
    .get('/', () => 'hi', {
        beforeHandle() {
            console.log('Elysia')
        }
    })

macro shine when a logic is more complex than accepting a new function, for example creating an authorization layer for each route.

typescript
import { 
Elysia
} from 'elysia'
import {
auth
} from './auth'
const
app
= new
Elysia
()
.
use
(
auth
)
.
get
('/', ({
user
}) =>
user
, {
isAuth
: true,
role
: 'admin'
})

Macro v2 can also register a new property to the context, allowing us to access the value directly from the context.

The field can accept anything ranging from string to function, allowing us to create a custom life cycle event.

macro will be executed in order from top-to-bottom according to definition in hook, ensure that the stack should be handle in correct order.

Resolve

You add a property to the context by returning an object with a resolve function.

ts
import { 
Elysia
} from 'elysia'
new
Elysia
()
.
macro
({
user
: (
enabled
: true) => ({
resolve
: () => ({
user
: 'Pardofelis'
}) }) }) .
get
('/', ({
user
}) =>
user
, {
user
: true
})

In the example above, we add a new property user to the context by returning an object with a resolve function.

Here's an example that macro resolve could be useful:

  • perform authentication and add user to the context
  • run an additional database query and add data to the context
  • add a new property to the context

Property shorthand

Starting from Elysia 1.2.10, each property in the macro object can be a function or an object.

If the property is an object, it will be translated to a function that accept a boolean parameter, and will be executed if the parameter is true.

typescript
import { Elysia } from 'elysia'

export const auth = new Elysia()
    .macro({
    	// This property shorthand
    	isAuth: {
      		resolve() {
     			return {
         			user: 'saltyaom'
          		}
      		}
        },
        // is equivalent to
        isAuth(enabled: boolean) {
        	if(!enabled) return

        	return {
				resolve() {
					return {
						user
					}
				}
         	}
        }
    })