---
title: "Référence d'API — @nodefony/framework — decorators"
source: docs/api/framework/decorators.md
url: https://nodefony.github.io/nodefony-core/docs/api/framework/decorators/
---


[Documentation](../../../) › [Référence d'API](../../) › [`@nodefony/framework`](../) › decorators

> Générée depuis les déclarations de types publiées de `@nodefony/framework` **10.0.0-beta.5** : exactement ce que reçoit une application qui l'installe. Cette page n'existe dans aucun dépôt — pour la corriger, on corrige le TSDoc du code.

## `@nodefony/framework`

`import { … } from "@nodefony/framework"` — 48 symboles.

### Fonctions (20)

#### `Anonymous`

```ts
function Anonymous(): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

Déclare une action (méthode) ou un contrôleur (classe) **publique** : skip l'autorisation (override un `@IsGranted` de classe sur cette méthode) ET skip l'authentification (réutilise le mécanisme `@BypassFirewall` → pas de 401 en zone protégée). L'alias lisible de « permitAll » (mental model Spring). Pour un login, une sonde de liveness, une page publique d'un contrôleur par ailleurs protégé.

#### `Body`

```ts
function Body(keyOrOptions?: string | { stream?: boolean; }): (target: object, propertyKey: string, parameterIndex: number) => void
```

Décorateur de paramètre `@Body` : - `@Body()` → body parsé entier · `@Body("field")` → un champ du body parsé. - `@Body({ stream: true })` → **flux brut** de la requête (`Readable`), sans parse en mémoire (P2.9 — gros uploads sans pic RAM ; le pipeline saute le parse busboy/JSON pour cette route).

#### `BypassFirewall`

```ts
function BypassFirewall(target: object, propertyKey?: string, descriptor?: PropertyDescriptor): any
```

Déclare une route (décorateur de **méthode**) ou tout un contrôleur (décorateur de **classe**) comme **PUBLIQUE** : le firewall ne s'exécute pas (`Route.bypassFirewall`). Pour la **liveness** (`/health`, `/info` — sondes k8s/monitoring NON authentifiées, ping pré-login), les **webhooks signés**, ou un endpoint d'auth (login). Sucre déclaratif sur l'option `RouteOptions.bypassFirewall` (les deux coexistent ; l'option l'emporte).

#### `Csp`

```ts
function Csp(directives: CspDirectives): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

`@Csp({ "frame-src": [...] })` — déclare des directives CSP **additionnelles** pour l'action (méthode) ou tout le contrôleur (classe). Distinct de `registerCspOrigins` (besoins PERMANENTS d'un module, ex. Vite) : ici c'est le besoin ponctuel d'UNE réponse (embarquer une iframe YouTube, autoriser une CDN).

#### `Domain`

```ts
function Domain(patterns: string | string[]): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

Restreint une route (décorateur de **méthode**) ou tout un contrôleur (décorateur de **classe**) à un ou plusieurs vhosts. Source de vérité du domaine de routing — le `host` posé ici alimente `Route.host`, compilé en RegExp ancrée/wildcard (matcher partagé `@nodefony/http`). Domaine non servi par la route → 403.

#### `Header`

```ts
function Header(key: string, value: string): (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor
```

Ajoute un en-tête à la réponse d'une action.

#### `HttpCode`

```ts
function HttpCode(statusCode: number): (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor
```

Fixe le code de statut HTTP de la réponse d'une action.

#### `Idempotent`

```ts
function Idempotent(options?: { required?: boolean; }): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

`@Idempotent()` — protège une **mutation** (POST/PUT/PATCH/DELETE) d'un controller userland contre le double-effet d'un rejeu (double-clic, reconnexion socket, retry réseau), via une `Idempotency-Key` cliente (modèle Stripe, conforme `draft-ietf-httpapi-idempotency-key-header`). No-op sur les méthodes sûres (GET…).

#### `IsGranted`

```ts
function IsGranted(attribute: string | readonly string[], options?: { subject?: string; }): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

Exige une autorisation pour l'action (décorateur de **méthode**) ou tout le contrôleur (décorateur de **classe**).

#### `Redirect`

```ts
function Redirect(url: string, statusCode?: number): (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor
```

Redirige la réponse d'une action vers une autre URL.

#### `RequireAuthentication`

```ts
function RequireAuthentication(options?: IRequireAuthenticationOptions): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

Exige une connexion RÉCENTE et/ou faite avec certains moyens pour l'action (décorateur de méthode) ou tout le contrôleur (décorateur de classe).

#### `RequireScope`

```ts
function RequireScope(scope: string | readonly string[]): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

Exige un **scope** (`api:action`) pour l'action (décorateur de **méthode**) ou tout le contrôleur (décorateur de **classe**). Axe d'autorisation **distinct des rôles** (`@IsGranted`) : un scope **downscope** un jeton MACHINE délégué (clé API, JWT d'agent, OAuth) — il est un **no-op** pour une session humaine, dont les droits sont portés par ses rôles (cf `ScopeVoter`).

#### `Scope`

```ts
function Scope(scope: ControllerScope): (target: { scope?: ControllerScope; }) => void
```

Déclare la portée d'instanciation d'un contrôleur — pose le statique `scope` de la classe (hérité de `Controller`, défaut `"singleton"`). Lu par le constructeur de `Controller` (`new.target`) et par le `Resolver` : 0 Reflect.

#### `UseSession`

```ts
function UseSession(options?: UseSessionOptions): (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

Déclare qu'une route (décorateur de **méthode**) ou tout un contrôleur (décorateur de **classe**) a besoin d'une **session serveur**. C'est l'unique façon d'activer une session (avec la reprise auto d'un cookie existant — L1) : il n'y a plus de `sessionAutoStart` global « démarre partout » (le moteur du ×23). Lazy par défaut — aucune session pour une route qui n'en déclare pas.

#### `buildContextParamArgs`

```ts
function buildContextParamArgs(metas: readonly ParamMeta[], context: IParamArgSource, paramsMap: Record<string, unknown>, queryOverride?: Record<string, unknown>): unknown[]
```

Résout les paramètres décorés d'une action depuis un `Context` — la mise en forme UNIQUE, appelée par le Resolver (routes HTTP et WS) comme par les actions `@RealtimeAction`, pour qu'un décorateur ne puisse pas prendre deux sens selon le transport.

#### `controller`

```ts
function controller(prefix: string): <T extends ControllerConstructor & { prefix?: string; }>(mycontroller: T) => T
```

Declaration Controller

#### `controllers`

```ts
function controllers(targets: TypeController<Controller>[] | TypeController<Controller>): <T extends Constructor<Module>>(constructor: T) => T
```

Rattache un ou plusieurs contrôleurs à un module, dont ils suivent le cycle de vie.

#### `getParamArgsMeta`

```ts
function getParamArgsMeta(proto: object, method: string | symbol): readonly ParamMeta[] | null
```

Les paramètres décorés d'une méthode (`@Body`, `@CurrentUser`…), ou `null` si elle n'en porte aucun. Lecture `Reflect` : à faire une fois, hors du chemin de chaque requête.

#### `route`

```ts
function route(name: string, options: RouteOptions & { schema?: undefined; bodyStream?: false; }): RouteMethodDecorator
function route<S extends IRouteSchema>(name: string, options: RouteOptionsWithSchema<S> & { bodyStream?: false; }): SchemaRouteMethodDecorator<S, false>
function route<S extends IRouteSchema & { readonly body?: undefined; }>(name: string, options: RouteOptionsWithSchema<S> & { bodyStream: true; }): SchemaRouteMethodDecorator<S, true>
```

Crée une route avec le nom et les options spécifiés.

#### `routeExpectsBodyStream`

```ts
function routeExpectsBodyStream(routeDef: { controller?: { prototype: object; } | null; classMethod?: string; bodyStream?: boolean; }): boolean
```

P2.9 — Indique si l'action d'une route attend le **flux brut** du body (un paramètre `@Body({ stream:true })`). Le résultat est **mémoïsé** sur `route.bodyStream` : lecture `Reflect` au 1er appel, O(1) ensuite → 0 coût hot-path. Lu **en amont** par `handleHttp` (avant le parse) pour décider de sauter le parse busboy/JSON. Typage structurel (pas d'import `Route` → 0 cycle).

### Constantes (20)

#### `All`

```ts
const All: IHttpMethodDecorator
```

`@All` — route sans restriction de méthode : matche **toutes** les méthodes HTTP (équivalent NestJS `@All()`). N'émet aucun requirement `methods`, donc `Route.matchRequirements` ne lève jamais 405 sur la méthode.

#### `Cookie`

```ts
const Cookie: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `CsrfExempt`

```ts
const CsrfExempt: () => (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

`@CsrfExempt()` — opt-OUT de la défense CSRF pour une route, **en conservant l'authentification et l'autorisation** (≠ `@Anonymous`/`@BypassFirewall` qui coupent l'auth). Pour un webhook ou une API recevant un POST cross-origin légitime, dont la requête est authentifiée autrement (signature HMAC du provider, clé API). Classe = toutes les actions. Marqueur seul (0 logique sécu ici).

#### `CsrfProtect`

```ts
const CsrfProtect: () => (target: object, propertyKey?: string, descriptor?: PropertyDescriptor) => any
```

`@CsrfProtect()` — opt-IN à la défense CSRF **synchronizer token** (double-submit signé HMAC) EN PLUS de la défense globale Fetch Metadata/Origin (étape 1, toujours active). Pour les mutations à haute valeur (changement de mot de passe, virement) : une requête sûre vers la route SÈME le cookie lisible `csrf-token` ; la mutation DOIT rejouer ce token dans l'en-tête `x-csrf-token` (sinon 403). Classe = toutes les actions. N'écrit qu'un marqueur (0 import `@nodefony/security`, 0 cycle).

#### `CurrentUser`

```ts
const CurrentUser: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

`@CurrentUser() user: IUser` — injecte l'utilisateur de l'ALS (jamais le credential).

#### `Delete`

```ts
const Delete: IHttpMethodDecorator
```

#### `Get`

```ts
const Get: IHttpMethodDecorator
```

#### `Head`

```ts
const Head: IHttpMethodDecorator
```

#### `Headers`

```ts
const Headers: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `Options`

```ts
const Options: IHttpMethodDecorator
```

#### `Param`

```ts
const Param: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `Patch`

```ts
const Patch: IHttpMethodDecorator
```

#### `Post`

```ts
const Post: IHttpMethodDecorator
```

#### `Put`

```ts
const Put: IHttpMethodDecorator
```

#### `Query`

```ts
const Query: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `Req`

```ts
const Req: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `Res`

```ts
const Res: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `Session`

```ts
const Session: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `UploadedFile`

```ts
const UploadedFile: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

#### `UploadedFiles`

```ts
const UploadedFiles: (key?: string) => (target: object, propertyKey: string, parameterIndex: number) => void
```

### Interfaces (7)

#### `IAuthenticationRequirement`

```ts
interface IAuthenticationRequirement
```

Exigence d'authentification **figée** d'une action — fusion classe + méthode au plus strict (âge le plus court, moyens réunis), calculée UNE fois par route. Objet partagé entre requêtes : ne jamais muter.

- `readonly maxAge: number | null` — Âge maximal en secondes, `null` = sans limite.
- `readonly amr: readonly string[]` — Moyens exigés, tous présents.

#### `IHttpMethodDecorator`

```ts
interface IHttpMethodDecorator
```

Un décorateur de méthode HTTP (`@Get`, `@Post`…). Sans schéma, la signature de l'action est libre (décorateurs de paramètre) ; avec `schema`, l'action reçoit un argument unique `RouteInput<S>`, vérifié à la compilation.

- `(path?: string, options?: MethodDecoratorOptions & { schema?: undefined; bodyStream?: false; }): RouteMethodDecorator`
- `<S extends IRouteSchema>(path: string, options: MethodDecoratorOptions & { schema: S; bodyStream?: false; }): SchemaRouteMethodDecorator<S, false>`
- `<S extends IRouteSchema & { readonly body?: undefined; }>(path: string, options: MethodDecoratorOptions & { schema: S; bodyStream: true; }): SchemaRouteMethodDecorator<S, true>`

#### `IParamArgSource`

```ts
interface IParamArgSource
```

Ce qu'un `Context` — HTTP comme WebSocket — offre à la résolution des paramètres décorés. Forme structurelle : le framework n'importe pas les classes de contexte pour la lire.

- `readonly request?: unknown` — La requête du contexte (HTTP, ou l'upgrade d'une connexion WS).
- `readonly response?: unknown` — La réponse du contexte.
- `readonly session?: unknown` — La session, quand le contexte en porte une.
- `getRequestCookies(name?: string): unknown` — Lit un cookie de la requête, ou tous sans argument.

#### `IRequireAuthenticationOptions`

```ts
interface IRequireAuthenticationOptions
```

Options de `RequireAuthentication`.

- `readonly maxAge?: number` — Âge maximal de la connexion, en secondes.
- `readonly amr?: readonly string[]` — Moyens d'authentification EXIGÉS, tous présents (RFC 8176) : `"pwd"` mot de passe, `"otp"` code à usage unique, `"pop"` clé d'accès.

#### `ParamMeta`

```ts
interface ParamMeta
```

- `source: ParamSource`
- `key?: string`
- `index: number`
- `stream?: boolean` — P2.9 — `@Body({ stream: true })` : injecte le **flux brut** de la requête (`IncomingMessage`, un `Readable`) au lieu du body parsé en mémoire.

#### `SecurityClause`

```ts
interface SecurityClause
```

Une clause `@IsGranted` : un OU plusieurs attributs (OR interne), sujet optionnel. `@IsGranted("ROLE_ADMIN")` → `{ anyOf: ["ROLE_ADMIN"] }` ; `@IsGranted(["A","B"])` → `{ anyOf: ["A","B"] }` (un seul suffit) ; `@IsGranted("doc.edit", { subject: "id" })` → le param de route `id` est passé au voter.

- `readonly anyOf: readonly string[]` — Attributs en OR — un seul accordé suffit pour valider la clause.
- `readonly subjectParam?: string` — Nom du paramètre de route passé comme `subject` au voter (optionnel).

#### `SecurityRequirement`

```ts
interface SecurityRequirement
```

Exigence d'autorisation **figée** d'une action — calculée UNE fois par route (fusion classe + méthode) puis gelée sur `RouteActionMeta.security`. Objet PARTAGÉ entre toutes les requêtes : ne jamais muter. `null` (hors de ce type) = aucune garde → coût nul sur le hot path.

- `readonly clauses: readonly SecurityClause[]` — Clauses en AND — toutes doivent être accordées (chacune est un OR interne).
- `readonly hasRoleClause: boolean` — L'exigence porte-t-elle au moins une clause de **rôle** (`@IsGranted`), par opposition à des clauses de **scope** seules (`@RequireScope`) ?

### Types (1)

#### `CspDirectives`

```ts
type CspDirectives = Record<string, readonly string[]>
```

Directives CSP additionnelles déclarées par une action (`@Csp`) : `directive → sources` (ex. `{ "frame-src": ["https://youtube.com"] }`). Structurellement compatible avec `CspFragment` (@nodefony/security) — aucun import cross-module (0 cycle). Mergé additivement dans le CSP de la réponse par le firewall, UNIQUEMENT sur les routes qui en déclarent (cold path).

---

[← Toutes les références d'API](../../)
