Skip to Content

Adapter Hooks

OberonPluginAdapter is composed from four parts:

type OberonPluginAdapter = OberonInitAdapter & OberonDatabaseAdapter & OberonCanAdapter & OberonSendAdapter

OberonInitAdapter

Lifecycle hooks used during setup and build.

type OberonInitAdapter = { prebuild: () => Promise<void> }

Use prebuild for work that must happen before build output is produced, such as migrations or initialisation.

OberonDatabaseAdapter

Database plugins own the main persistence surface. In code this is:

type OberonDatabaseAdapter = Partial<OberonInitAdapter> & OberonBaseAdapter & OberonAuthAdapter

Content and media methods

  • addPage
  • deletePage
  • getAllPages
  • getPageData
  • updatePageData
  • addImage
  • deleteImage
  • getAllImages

User and role methods

  • addUser
  • deleteUser
  • getAllUsers
  • changeRole

Site and key-value methods

  • getSite
  • updateSite
  • getKV
  • putKV
  • deleteKV

Auth.js methods included in database responsibilities

  • createSession
  • createUser
  • createVerificationToken
  • deleteSession
  • deleteUser
  • getSessionAndUser
  • getUser
  • getUserByAccount
  • getUserByEmail
  • linkAccount
  • unlinkAccount
  • updateSession
  • updateUser
  • useVerificationToken

If your plugin is the database layer used by Oberon auth, it is expected to own those Auth.js adapter methods as part of the same plugin surface.

OberonCanAdapter

Permission and session helpers:

  • getCurrentUser
  • hasPermission
  • signIn
  • signOut

hasPermission receives user, action, and permission, and returns a boolean synchronously.

OberonSendAdapter

Send plugins provide verification delivery:

  • sendVerificationRequest
type OberonSendAdapter = { sendVerificationRequest: (props: { email: string token: string url: string }) => Promise<void> }

Minimal custom implementations

Database-oriented custom plugin:

import { USE_DEVELOPMENT_DATABASE_PLUGIN, notImplemented, type OberonDatabaseAdapter, type OberonInitAdapter, type OberonPlugin, } from "@oberoncms/core" export const databasePlugin: OberonPlugin = () => ({ name: "Custom Database Plugin", disabled: USE_DEVELOPMENT_DATABASE_PLUGIN, adapter: { prebuild: notImplemented("prebuild"), addPage: notImplemented("addPage"), addImage: notImplemented("addImage"), addUser: notImplemented("addUser"), deletePage: notImplemented("deletePage"), deleteImage: notImplemented("deleteImage"), deleteKV: notImplemented("deleteKV"), deleteUser: notImplemented("deleteUser"), changeRole: notImplemented("changeRole"), getAllImages: notImplemented("getAllImages"), getAllPages: notImplemented("getAllPages"), getAllUsers: notImplemented("getAllUsers"), getKV: notImplemented("getKV"), getPageData: notImplemented("getPageData"), getSite: notImplemented("getSite"), putKV: notImplemented("putKV"), updatePageData: notImplemented("updatePageData"), updateSite: notImplemented("updateSite"), createSession: notImplemented("createSession"), createUser: notImplemented("createUser"), createVerificationToken: notImplemented("createVerificationToken"), deleteSession: notImplemented("deleteSession"), getSessionAndUser: notImplemented("getSessionAndUser"), getUser: notImplemented("getUser"), getUserByAccount: notImplemented("getUserByAccount"), getUserByEmail: notImplemented("getUserByEmail"), linkAccount: notImplemented("linkAccount"), unlinkAccount: notImplemented("unlinkAccount"), updateSession: notImplemented("updateSession"), updateUser: notImplemented("updateUser"), useVerificationToken: notImplemented("useVerificationToken"), } satisfies OberonInitAdapter & OberonDatabaseAdapter, })

Send-oriented custom plugin:

import "server-cli-only" import { USE_DEVELOPMENT_SEND_PLUGIN, type OberonPlugin, type OberonSendAdapter, } from "@oberoncms/core" const EMAIL_FROM = process.env.EMAIL_FROM const SEND_SECRET = process.env.SEND_SECRET async function sendEmail( message: { from: string subject: string text: string to: string }, secret: string, ) { void message void secret throw new Error("sendEmail is not implemented") } export const sendPlugin: OberonPlugin = () => ({ name: "Custom Send", disabled: USE_DEVELOPMENT_SEND_PLUGIN, adapter: { sendVerificationRequest: async ({ email, token, url }) => { if (!SEND_SECRET) throw new Error("No SEND_SECRET configured") if (!EMAIL_FROM) throw new Error("No EMAIL_FROM configured") await sendEmail( { from: EMAIL_FROM, subject: "One time login to Oberon CMS", text: `Sign in with code\n\n${token}\n\n${url}\n\n`, to: email, }, SEND_SECRET, ) }, } satisfies OberonSendAdapter, })
Last updated on