npm package: @definitely-fine/hono
Description: Hono middleware and handler helpers for definitely-fine scenarios.
Latest version: 0.1.1

# @definitely-fine/hono

`@definitely-fine/hono` connects `definitely-fine` scenario context to Hono middleware and route handling.

It reads a scenario id from a request header and runs Hono middleware or handlers inside the matching active scenario context.

## Installation

```bash
pnpm add definitely-fine @definitely-fine/hono hono
```

## Important

> [!IMPORTANT]
> Do not leave scenario activation enabled in production by accident.
>
> `@definitely-fine/hono` will activate scenario context whenever the request header is present.
> In production, pair this package with `createRuntime({ enabled: false })` in your core runtime, or avoid installing the middleware and wrappers there entirely.

Core runtime protection:

```ts
import { createRuntime } from "definitely-fine";

const runtime = createRuntime<DemoContract>({
  enabled: process.env.NODE_ENV !== "production",
});
```

Optional middleware guard:

```ts
import { Hono } from "hono";
import { definitelyFineScenarioMiddleware } from "@definitely-fine/hono";

const app = new Hono();

if (process.env.NODE_ENV !== "production") {
  app.use("*", definitelyFineScenarioMiddleware());
}
```

## What This Package Does

This package does not replace the core runtime. You still create your scenarios and wrapped runtime with `definitely-fine`.

Its job is narrower:

- define the scenario header name constant
- read that header from `Headers`, `Request`, or Hono `Context`
- run Hono handlers or middleware inside `runWithRuntimeScenarioContext()`

```mermaid
flowchart LR
  subgraph C[Client or browser process]
    C1[request]
    C2[x-definitely-fine-scenario-id header]
  end

  subgraph H[Hono server process]
    H1[@definitely-fine/hono middleware or handler wrapper]
    H2[runWithRuntimeScenarioContext]
    H3[definitely-fine runtime]
    H4[wrapped app service or function]
  end

  subgraph S[Shared scenario storage]
    S1[(persisted scenario JSON)]
  end

  C1 --> C2 --> H1
  H1 --> H2 --> H3 --> H4
  H3 -- load active scenario --> S1
```

## App Middleware

Use `definitelyFineScenarioMiddleware()` when you want one app-level middleware instead of wrapping every route.

```ts
import { Hono } from "hono";
import { definitelyFineScenarioMiddleware } from "@definitely-fine/hono";

const app = new Hono();

app.use("*", definitelyFineScenarioMiddleware());
```

Downstream handlers then run inside the matching scenario automatically when the request includes the scenario header.

## Route Handlers

Use `withDefinitelyFineScenario()` when you want to scope scenario activation to a specific Hono handler.

```ts
import { Hono } from "hono";
import { withDefinitelyFineScenario } from "@definitely-fine/hono";

import { incrementCounter } from "../lib/demo-runtime";

const app = new Hono();

app.post(
  "/api/counter",
  withDefinitelyFineScenario((context) => {
    return context.json(incrementCounter());
  }),
);
```

If the request does not include the scenario header, the handler runs normally.

## Header Name

The exported header constant is `DEFINITELY_FINE_SCENARIO_HEADER`.

```ts
import { DEFINITELY_FINE_SCENARIO_HEADER } from "@definitely-fine/hono";

const headers = {
  [DEFINITELY_FINE_SCENARIO_HEADER]: "scenario-id",
};
```

## Typical Setup

1. Create and save a scenario with `definitely-fine`.
2. Add `definitelyFineScenarioMiddleware()` at app level, or wrap specific handlers with `withDefinitelyFineScenario()`.
3. Send the scenario id in the request header.
4. Let your core runtime wrappers decide which calls are intercepted.

For safety, production apps should normally disable the core runtime with `enabled: false` and optionally skip this middleware or these wrappers entirely.

## With Playwright

This package pairs naturally with [`@definitely-fine/playwright`](../playwright/README.md), which can create browser contexts that already include the scenario header.