npm package: @irondome/next
Description: Next.js App Router helpers for Irondome permissions
Latest version: 0.1.3

# @irondome/next

> Integração **Next.js** (App Router) — o mesmo `can()` no middleware, APIs, tRPC e UI.

**Pilar:** *como* o pedido HTTP chega ao motor PBAC — rotas, JSON, hooks e Server Actions.

Parte do monorepo **[Irondome](../../README.md)** — espelha as secções **Middleware**, **Hook React** e **tRPC** do [README principal](../../README.md).

---

## O que é?

`@irondome/next` liga **`@irondome/core`** (e opcionalmente **`@irondome/auth`**) ao ciclo de vida do Next.js: **`createRoutePermissionMiddleware`**, **`runPermissionGuard`**, **`usePermission`**, **`createIrondomeContext`**, **`irondomePermission`**, **`withPermission`**, respostas **`forbiddenJson` / `unauthorizedJson`**.

Não redefine políticas — apenas transporta `Subject` + `can()` para o sítio certo.

---

## Instalação

```bash
pnpm add @irondome/next @irondome/core @irondome/auth next react
```

---

## Dependências

| Tipo | Pacotes |
|------|---------|
| **Peer** | `@irondome/core`, `@irondome/auth`, `next`, `react` |

---

## O que inclui

| API | Uso |
|-----|-----|
| `createRoutePermissionMiddleware` | `middleware.ts` — mesmas regras que no servidor |
| `runPermissionGuard` | `app/api/.../route.ts` |
| `forbiddenJson` / `unauthorizedJson` | Respostas 403 / 401 |
| `usePermission` | Componentes `'use client'` |
| `createIrondomeContext` | Contexto tRPC com `can` / `authorize` |
| `irondomePermission` | Middleware de procedure tRPC |
| `withPermission` | Server Actions |

---

## Exemplo rápido (middleware)

```ts
import { createRoutePermissionMiddleware } from "@irondome/next";
import { actions, pageResource } from "@irondome/core";
import { verifyToken } from "@irondome/auth/jwt";
import { can } from "./lib/permissions";

export default createRoutePermissionMiddleware({
  getSubject: async (req) => {
    const token = /* cookie */;
    const payload = await verifyToken(token, process.env.JWT_SECRET!);
    return payload ? { id: payload.sub, roles: payload.roles, orgId: payload.orgId } : null;
  },
  can,
  publicPaths: ["/", "/api/auth/*"],
  rules: [
    { match: (p) => p.startsWith("/admin"), action: actions.page.visit, resource: (p) => pageResource(p) },
  ],
});
```

*(Igual ao [README do monorepo](../../README.md), secção Middleware.)*

---

## Hook React (client)

```tsx
import { usePermission } from "@irondome/next";
import { namedResource } from "@irondome/core";

const { allowed } = usePermission(can, user, "resource:delete", namedResource("post", post.id));
return allowed ? <DeleteButton /> : null;
```

---

## tRPC

```ts
import { createIrondomeContext, irondomePermission } from "@irondome/next";
import { namedResource } from "@irondome/core";
import { can } from "@/lib/irondome/permissions";

export const createTRPCContext = async () => {
  const subject = await getServerSubject();
  return { ...createIrondomeContext(can, subject) };
};

const canDelete = irondomePermission(can, "resource:delete", (input: { id: string }) =>
  namedResource("post", input.id),
);
```

*(Detalhes no [README do monorepo](../../README.md), secção tRPC.)*

---

## Relação com outros pacotes

| Pacote | Função |
|--------|--------|
| `@irondome/core` | Exporta `can` / `createPermissions` |
| `@irondome/auth` | `verifyToken` no Edge; sessão em Server Components |

---

## Documentação

| Recurso | Ligação |
|---------|---------|
| Monorepo | [README Irondome](../../README.md) |
| Quatro pilares | [Guia dos pilares](../../docs/guia-dos-pilares.md) |
| Publicar no npm | [npm-publish](../../docs/npm-publish.md) |

---

## Licença

MIT © rbxyz