Plugin API Reference
Complete API reference for DeesseJS plugins
Plugin API Reference
Complete reference for the DeesseJS Plugin System API.
definePlugin
The main function for defining a plugin.
import { definePlugin } from '@deessejs/core'
const plugin = definePlugin<PluginOptions>(config)Configuration
interface PluginConfig<Options = any> {
name: string // Unique plugin identifier
version: string // Semantic version
description?: string // Plugin description
author?: string // Plugin author
license?: string // Plugin license
activate: (options: Options) => PluginExtension | void
deactivate?: () => void | Promise<void>
}Plugin Extension
interface PluginExtension {
collections?: CollectionExtension
admin?: AdminExtension
api?: ApiExtension
hooks?: HooksExtension
fields?: FieldExtension[]
context?: Record<string, any>
}Collection Extension
Extend or create collections.
Extend Collections
collections: {
extend: {
[collectionName: string]: {
fields?: Field[]
hooks?: CollectionHooks
admin?: CollectionAdminConfig
}
}
}Create Collections
collections: {
create: CollectionDefinition[]
}Example
export const plugin = definePlugin({
name: 'my-plugin',
activate() {
return {
collections: {
extend: {
posts: {
fields: [
{ name: 'customField', type: 'string' }
],
hooks: {
beforeCreate: async ({ data }) => {
console.log('Creating post:', data)
}
}
}
},
create: [
{
name: 'comments',
fields: [
{ name: 'content', type: 'text' },
{ name: 'post', type: 'reference', relation: 'posts' }
]
}
]
}
}
}
})Admin Extension
Extend the admin dashboard.
interface AdminExtension {
navigation?: NavigationItem[]
pages?: AdminPage[]
widgets?: AdminWidget[]
settings?: AdminSetting[]
branding?: BrandingConfig
}Navigation Items
type NavigationItem =
| NavigationLink
| NavigationGroup
| NavigationSeparator
interface NavigationLink {
type: 'link'
title: string
href: string
icon?: string
permissions?: string[]
}
interface NavigationGroup {
type: 'group'
title: string
items: string[] // Collection names or custom paths
icon?: string
}
interface NavigationSeparator {
type: 'separator'
}Admin Pages
interface AdminPage {
id: string
title: string
path: string
component: string // Path to component
icon?: string
permissions?: string[]
layout?: 'default' | 'blank'
}Admin Widgets
interface AdminWidget {
id: string
component: string // Path to component
position: 'top' | 'left' | 'right' | 'bottom'
size: 'small' | 'medium' | 'large'
}Admin Settings
interface AdminSetting {
id: string
label: string
component: string
save?: (values: any) => Promise<void>
load?: () => Promise<any>
}API Extension
Extend the API with custom routes.
interface ApiExtension {
routes: ApiRoute[]
middleware?: ApiMiddleware[]
}
interface ApiRoute {
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
path: string
handler: string // Path to handler
middleware?: string[]
}Route Handler
// api/custom/route.ts
import { NextRequest, NextResponse } from 'next/server'
export async function GET(request: NextRequest) {
const data = await fetchData()
return NextResponse.json(data)
}
export async function POST(request: NextRequest) {
const body = await request.json()
const result = await processData(body)
return NextResponse.json(result)
}Hooks Extension
Hook into DeesseJS lifecycle events.
interface HooksExtension {
serverInit?: (context: ServerContext) => void | Promise<void>
request?: (context: RequestContext) => void | Promise<void>
beforeCreate?: (context: ItemContext) => void | Promise<any>
afterCreate?: (context: ItemContext) => void | Promise<void>
beforeUpdate?: (context: ItemContext) => void | Promise<any>
afterUpdate?: (context: ItemContext) => void | Promise<void>
beforeDelete?: (context: ItemContext) => void | Promise<void>
afterDelete?: (context: ItemContext) => void | Promise<void>
}Hook Contexts
ServerContext
interface ServerContext {
app: any
config: DeesseConfig
env: Record<string, string>
}RequestContext
interface RequestContext {
req: NextRequest
res: NextResponse
user?: User
}ItemContext
interface ItemContext {
collection: string
id?: string
data?: any
item?: any
user?: User
}Hook Examples
hooks: {
beforeCreate: async ({ collection, data }) => {
// Modify data before creation
data.createdAt = new Date()
data.createdBy = user.id
return data
},
afterCreate: async ({ collection, item }) => {
// Perform side effects
await sendNotification(collection, item)
},
beforeUpdate: async ({ collection, id, data }) => {
// Validate or modify update
data.updatedAt = new Date()
return data
},
afterUpdate: async ({ collection, item }) => {
// Clear cache, send webhooks, etc.
await clearCache(collection, item.id)
}
}Field Extension
Create custom field types.
interface FieldExtension {
name: string
component: string // Path to component
validate?: (value: any) => boolean | string
sanitize?: (value: any) => any
defaultValue?: any
}Field Component
// fields/custom-field.tsx
'use client'
import { ChangeEvent } from 'react'
interface CustomFieldProps {
value: any
onChange: (value: any) => void
field: FieldConfig
error?: string
}
export function CustomField({
value,
onChange,
field,
error
}: CustomFieldProps) {
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
onChange(e.target.value)
}
return (
<div>
<label>{field.label}</label>
<input
type="text"
value={value || ''}
onChange={handleChange}
/>
{error && <span className="error">{error}</span>}
</div>
)
}Register Custom Field
export const plugin = definePlugin({
name: 'custom-fields',
activate() {
return {
fields: [
{
name: 'custom-field',
component: './fields/custom-field',
validate: (value) => {
if (!value) return 'This field is required'
return true
},
defaultValue: '',
},
],
}
},
})Plugin Context
Provide context and utilities to other parts of the application.
context: {
[key: string]: any
}Example
export const plugin = definePlugin({
name: 'api-client',
activate({ apiKey }) {
const client = new ApiClient(apiKey)
return {
context: {
api: client,
// Accessible via: usePluginContext('api')
},
}
},
})Plugin Options
Define configuration options for your plugin.
interface PluginOptions {
[key: string]: any
}
export const plugin = definePlugin<PluginOptions>({
name: 'configurable-plugin',
activate(options) {
// options is typed as PluginOptions
console.log('API Key:', options.apiKey)
console.log('Enabled:', options.enabled)
},
})Using Options
// deesse.config.ts
export const config = defineConfig({
plugins: [
configurablePlugin({
apiKey: process.env.API_KEY,
enabled: true,
timeout: 5000,
}),
],
})Utility Functions
Plugin Logger
import { createLogger } from '@deessejs/core'
const logger = createLogger('my-plugin')
logger.info('Plugin activated')
logger.warn('Warning message')
logger.error('Error occurred', error)Plugin Storage
import { createPluginStorage } from '@deessejs/core'
const storage = createPluginStorage('my-plugin')
await storage.set('key', 'value')
const value = await storage.get('key')
await storage.delete('key')Plugin Events
import { createEventEmitter } from '@deessejs/core'
const emitter = createEventEmitter('my-plugin')
emitter.on('event-name', (data) => {
console.log('Event received:', data)
})
emitter.emit('event-name', { some: 'data' })TypeScript Support
Type Definitions
// types.ts
export interface PluginOptions {
apiKey: string
enabled?: boolean
timeout?: number
}
export interface PluginContext {
client: ApiClient
logger: Logger
}
export const plugin = definePlugin<PluginOptions, PluginContext>({
name: 'typed-plugin',
activate(options: PluginOptions): PluginExtension<PluginContext> {
// Full type safety
},
})Type Exports
// Export types for plugin users
export type { PluginOptions, PluginConfig }
export type { CustomFieldProps }Best Practices
Performance
// Lazy load heavy components
component: () => import('./HeavyComponent')
// Cache expensive operations
const cached = useMemo(() => expensiveOperation(), [deps])Error Handling
try {
await riskyOperation()
} catch (error) {
logger.error('Operation failed', error)
// Provide fallback or graceful degradation
}Cleanup
export const plugin = definePlugin({
name: 'my-plugin',
activate() {
const interval = setInterval(doSomething, 1000)
return {
// Cleanup on deactivate
dispose: () => clearInterval(interval)
}
},
deactivate() {
// Cleanup logic
},
})Next Steps
- Learn how to Create Plugins
- View Plugin Examples
- Return to Plugins Overview