# shrext

> Simple middleware engine

Latest version **0.7.3** (published 2025-02-08) · MIT license · 0 weekly downloads

## Install

```sh
npm install shrext
pnpm add shrext
yarn add shrext
bun add shrext
```

## Health

**Score 40/100 (D)** — status: maintenance-mode.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.7.3 |
| Published | 2025-02-08 |
| First published | 2023-04-24 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 36.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Nazar Vovk |
| Maintainers | nazarvovk |
| Keywords | typescript, middleware |

## Links

- npm: https://www.npmjs.com/package/shrext
- npm.io page: https://npm.io/package/shrext

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 0.7.3 (latest) — 2025-02-08
- 0.7.2 — 2025-02-08
- 0.7.1 — 2025-02-08
- 0.7.0 — 2025-02-08
- 0.6.0 — 2024-10-28
- 0.5.0 — 2024-06-12
- 0.4.0 — 2023-07-14
- 0.4.0-rc.2 — 2023-05-16
- 0.4.0-rc.1 — 2023-05-16
- 0.4.0-rc.0 — 2023-05-15
- 0.3.0 — 2023-05-12
- 0.2.0 — 2023-04-26
- 0.1.11 — 2023-04-25
- 0.1.10 — 2023-04-24
- 0.1.9 — 2023-04-24
- … 9 more at https://npm.io/package/shrext/versions

## README

# Shrext

[![npm version](https://img.shields.io/npm/v/shrext.svg?maxAge=1000)](https://www.npmjs.com/package/shrext)
[![Test](https://github.com/nazarvovk/shrext/actions/workflows/test.yml/badge.svg)](https://github.com/nazarvovk/shrext/actions/workflows/test.yml)
[![npm downloads](https://img.shields.io/npm/dt/shrext.svg?maxAge=1000)](https://www.npmjs.com/package/shrext)
[![license](https://img.shields.io/npm/l/shrext.svg?maxAge=1000)](https://github.com/nazarvovk/shrext/blob/master/LICENSE)

A dead simple TypeScript middleware engine.

<p align="center">
  <img src="shrext.jpg" />
</p>

Shrext is a simple tool that helps you compose reusable middleware. Inspired by [Middy](https://github.com/middyjs/middy), made for *anything,* not just AWS Lambda.

## Installation

Install using `npm`:

```bash
npm install shrext
```

## Usage

### Basic Example

```typescript
import { MiddlewareFnObject, shrext } from './src'

type ApiHandler = (req: { auth_token: string }) => unknown

type User = { token: string }
type ContextWithUser = { user: User }

const handler = shrext<ApiHandler, ContextWithUser>((context) => {
  console.log(context.user.token)
})

const withUser: MiddlewareFnObject<ApiHandler, ContextWithUser> = {
  before: async (context) => {
    const {
      args: [req],
    } = context
    const user: User = await getUser(req.auth_token)
    Object.assign(context, { user })
  },
}
// attach the middleware
handler.use(withUser)

handler({ auth_token: 'qwerty' })
// Result: qwerty
```

Alternative composition:

```typescript
shrext<ApiHandler, ContextWithUser>()
  .use(withUser)
  .handler()
```

---

There are three types of middleware: `before`, `after`, and `onError`. All of them receive a `context` object, that by default has an `args` property - array of arguments the handler is called with. You can attach properties to context, as it's passed through the middleware layers.

The middleware call order:
- `before` - order in which it's attached
- `after` - reverse attach order
- `onError` - reverse attach order, like `after`

---
Some rules and behavior to keep in mind:

  1. Handler and every middleware are always awaited, the call on instance always returns a `Promise`
  2. The instance returned from `shrext()` is mutable and every method returns self. This allows to chain method calls, as well as compose separately, as shown above. 
  3. Because of the mutability, you should use `clone()` when reusing and extending shrex handler instances.


## API Reference

### `shrext<T extends AnyFunc, TContext>(handler?: Handler<T, TContext>)`
Creates a Shrext instance.

### `use(middleware: MiddlewareFnObject<TFunction, TContext>, options?: MiddlewareOptions)`
Attaches a middleware object with `before`, `after`, or `onError` hooks.

### `before(beforeMiddleware: BeforeMiddlewareFn<T, TContext>, options?: MiddlewareOptions)`
Helper shortcut for `.use({ before })`

### `after(afterMiddleware: AfterMiddlewareFn<T, TContext>, options?: MiddlewareOptions)`
Helper shortcut for `.use({ after })`

### `onError(onErrorMiddleware: OnErrorMiddlewareFn<T, TContext>, options?: MiddlewareOptions)`
Helper shortcut for `.use({ onError })`

### `setHandler(handler: Handler<T, TContext>)`
Set the function handler. Overwrite if it was set previously.

### `remove(id: string, options?: RemoveOptions)`
Removes middleware by ID. You can pass `id` in `use()` and the helper shortcuts in the second options argument.

Optionally pass options to specify which parts of the middleware to remove.

### `clone()`
Returns a new instance with the middleware copied, that can be modified independently.


## License

Licensed under [MIT License](LICENSE). Copyright (c) 2025 [Nazarii Vovk](https://github.com/nazarvovk).

---
_Source: https://npm.io/package/shrext · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
