Astro
permdock/astro is an onRequest middleware that sets context.locals.permdock, a protect wrapper for endpoints, and the decision endpoint for islands.
Purpose
permdock/astro guards Astro on-demand routes: middleware() is onRequest in src/middleware.ts, protect wraps an endpoint in src/pages, and getSnapshot gives a page the snapshot it passes to a permdock/react, permdock/vue, permdock/svelte or permdock/solid island. It needs output: "server" or a route with prerender = false; a prerendered page has no request to check.
API
import { createPermDock } from "permdock/astro";
import { policy } from "./policy";
export const { middleware, protect, getSnapshot, permdockHandler } =
createPermDock(policy, { subject: (context) => context.locals.user });export const onRequest = middleware();export const PATCH = protect(permissions.post.update, (context) =>
loadPost(context.params.id),
)((context) => Response.json(update(context.locals.permdockData)));export const { GET, POST } = permdockHandler();| Export | Role |
|---|---|
middleware() | A MiddlewareHandler for onRequest, or one step of sequence. Sets context.locals.permdock and calls next(). A bad Web Bot Auth signature answers 401. |
protect(target, data?, options?) | Returns a wrapper for an endpoint. A grant sets context.locals.permdock and context.locals.permdockData; a refusal is the Problem Details response. The endpoint keeps its own APIContext type. |
withPermDock(handler) | Types context.locals.permdock for an endpoint without a check, and answers a thrown PermDockError with Problem Details. |
getPermDock(context) | The instance for an endpoint, an action or a page's frontmatter, where Astro is the APIContext. |
getSnapshot(context, query?) | The snapshot a page passes to an island. |
connection(context, options?) | A kernel Connection for a stream. |
permdockHandler() | GET (snapshot) and POST (AuthZEN-shaped evaluations) for export const { GET, POST }. |
openapi | The kernel's OpenAPI hook contract. |
Request lifecycle
permdock/astro follows the shared adapter contract. What differs on Astro:
subject(context),tenant(context)andcontext(context)receive theAPIContext; read the user an earlier middleware put oncontext.locals.- The kernel caches one instance per request and tenant, so the middleware plus a guarded endpoint builds one instance.
- A loader that returns
nullorundefinedanswers404. - A page cannot return a Problem Details body; its frontmatter calls
getPermDock(Astro)and redirects or renders a fallback withAstro.redirectwhencanis false.
Why
Astro endpoints and middleware receive an APIContext with the Fetch Request and a request-scoped locals object, so the adapter is the kernel with Astro's context type. protect wraps the endpoint because Astro has no per-route middleware, and the wrapper keeps the endpoint's own APIContext. Islands are client components, so the UI side stays with the existing UI entries; this entry only adds the server half they need.
Example app
apps/examples/astro: src/lib/permissions.ts, src/lib/policy.ts and src/lib/permdock.ts, onRequest in src/middleware.ts, protect on PATCH /api/posts/[id] (granted) and POST /api/posts/[id]/publish (denied for member), and the decision endpoint at src/pages/api/permdock.ts. pnpm dev runs it; a production build needs an Astro server adapter, which the example does not install.
Related standards
- Problem Details.
- AuthZEN for the decision endpoint.
- Web Bot Auth.
Last updated on
SvelteKit
permdock/sveltekit is a handle hook that sets event.locals.permdock, a protect wrapper for +server.ts handlers, and the decision endpoint for permdock/svelte.
SolidStart
permdock/solid-start is an h3 middleware for SolidStart 2's createMiddleware, a protect wrapper for API routes, and the decision endpoint for permdock/solid.