{"_id":"@standard-server/core","_rev":"4-61b8b0661e7ff6d0a14dbbc6b697d703","name":"@standard-server/core","dist-tags":{"latest":"0.9.2"},"versions":{"0.8.3":{"name":"@standard-server/core","version":"0.8.3","keywords":["standard-server","http","server","client","request","response","transport-agnostic","body-parser","validator","sse","server-sent-events","streaming","typescript"],"license":"MIT","_id":"@standard-server/core@0.8.3","maintainers":[{"name":"dinwwwh","email":"dinwwwh@gmail.com"}],"dist":{"shasum":"184e0c05d0dc0a71c20f411b9fcb7c47484d3b1e","tarball":"https://registry.npmjs.org/@standard-server/core/-/core-0.8.3.tgz","fileCount":3,"integrity":"sha512-A/+pOyfFnl52M7+u8jnZNBM3kpBcOxgY9zHc9SmX/u+9yPpHOwQCvx6i+ruvyqEcOmXRXkHLCaLsFS38v8OBKA==","signatures":[{"sig":"MEUCIArgf1MXrQzLT7J9T5yByIN6WWPe+wubjMGHAEj2zbCJAiEA9F1SXRWatK/A10F+cmgK8k9uWwoFc42sW/I66ViEfgo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38516},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"funding":["https://github.com/sponsors/dinwwwh","https://opencollective.com/middleapi"],"scripts":{"build":"unbuild","type:check":"tsc -b"},"_npmUser":{"name":"dinwwwh","email":"dinwwwh@gmail.com"},"repository":{"url":"git+https://github.com/middleapi/standard-server.git","type":"git","directory":"packages/core"},"description":"The Standard Server contract: transport-agnostic request, response, body, and streaming types with body parsing rules, runtime validators, and SSE helpers shared by every adapter","directories":{},"sideEffects":false,"dependencies":{"@standard-server/shared":"0.8.3"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/core_0.8.3_1788683259227_0.04257135161506276","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@standard-server/core","version":"0.9.0","keywords":["standard-server","http","server","client","request","response","transport-agnostic","body-parser","validator","sse","server-sent-events","streaming","typescript"],"license":"MIT","_id":"@standard-server/core@0.9.0","maintainers":[{"name":"dinwwwh","email":"dinwwwh@gmail.com"}],"dist":{"shasum":"bb153de452d6733c832386f086304961b0247d62","tarball":"https://registry.npmjs.org/@standard-server/core/-/core-0.9.0.tgz","fileCount":6,"integrity":"sha512-yznlhJHHdZETepUuEjUomJjSsZm4BiNaFgrbCKxTvCNLYntcky0mTfgP2fJk6NTGb5Zh+tHjKcPPaYGytVF27Q==","signatures":[{"sig":"MEYCIQC4abghd/hMyhdIvTlHzCmyKZH5gqYU/nfSw+C/7QXumQIhAJSJypVAvXLhD5nQefIn1ZR4n18wWnBz2NanrUmooa9G","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIBrbHz8WphbOYEmRO40qHCxjMe5p4zVsz5Grvx5920klAiBFsg/BHKHcoW6GJkzSC6WhtfaFs0WnEPsjxtY9/oWr5A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@standard-server%2fcore@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":65335},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"funding":["https://github.com/sponsors/dinwwwh","https://opencollective.com/middleapi"],"scripts":{"build":"unbuild","type:check":"tsc -b"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:65935932-a786-477f-bf9f-c34f45e704bf"}},"repository":{"url":"git+https://github.com/middleapi/standard-server.git","type":"git","directory":"packages/core"},"description":"The Standard Server contract: transport-agnostic request, response, body, and streaming types with body parsing rules, runtime validators, and SSE helpers shared by every adapter","directories":{},"sideEffects":false,"dependencies":{"@standard-server/shared":"0.9.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/core_0.9.0_1788683693280_0.8035215764075125","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@standard-server/core","version":"0.9.1","keywords":["standard-server","http","server","client","request","response","transport-agnostic","body-parser","validator","sse","server-sent-events","streaming","typescript"],"license":"MIT","_id":"@standard-server/core@0.9.1","maintainers":[{"name":"dinwwwh","email":"dinwwwh@gmail.com"}],"dist":{"shasum":"485a9954a4822c68bcaeb181b64c92d1631412c3","tarball":"https://registry.npmjs.org/@standard-server/core/-/core-0.9.1.tgz","fileCount":6,"integrity":"sha512-wdCAdCH3M/GxNqEnDW/YQnzNz1T5hWuALzjh7lVyWwIZ2i9OBsOp4PFqFDhkAO2erfhOT1zVSrnJn9t8v6LbkQ==","signatures":[{"sig":"MEQCIDSkXr2hq89n4D3zf2tLBJVdk8QC5yRXB2dMomnecj+JAiAjh8QIKrNJRxamqGabbdUXe82SZsJtDgwXCCPZPTKFYw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDr0BEkRgGOgwnvvkvXfmFyoI0Dos2guTazEz9UUxE9JAIgeG1H2w+YtRl9552+lBq4VIdpiEqd5UtSeNLWVI8DKXA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@standard-server%2fcore@0.9.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":66142},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"funding":["https://github.com/sponsors/dinwwwh","https://opencollective.com/middleapi"],"scripts":{"build":"unbuild","type:check":"tsc -b"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:65935932-a786-477f-bf9f-c34f45e704bf"}},"repository":{"url":"git+https://github.com/middleapi/standard-server.git","type":"git","directory":"packages/core"},"description":"The Standard Server contract: transport-agnostic request, response, body, and streaming types with body parsing rules, runtime validators, and SSE helpers shared by every adapter","directories":{},"sideEffects":false,"dependencies":{"@standard-server/shared":"0.9.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/core_0.9.1_1789548907754_0.7234557360244633","host":"s3://npm-registry-packages-npm-production"}},"0.9.2":{"_id":"@standard-server/core@0.9.2","dist":{"shasum":"8eafe87ab9c6388cf9e5a99adaf909a5d8972ad0","tarball":"https://registry.npmjs.org/@standard-server/core/-/core-0.9.2.tgz","fileCount":6,"integrity":"sha512-P1tlRyxyM9n/toFH69/4O5Xn2V33iFszCy2xgZlqpng03nNNmFFH1ua6holdGbQ5CMeRMoJvlb8iezUhfak6Cw==","signatures":[{"sig":"MEUCIBscEFFGwT9QjOGIqPPv7MorC/V4WnWudD/ApzS3U+6rAiEAzAoli2Q4VH4ZU4qYXejLPJBVNbXMvBVuINQUUSQVVS8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAUp1gV7Y8rhPNEe/dnHJ02AXRjz35RtjZvkJSZZr8AEAiEArS9DEgqRYBSEasCxDF25gpMmvF/7NUdDrpx16S5Jv0s="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@standard-server%2fcore@0.9.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":66156},"name":"@standard-server/core","type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./package.json":"./package.json"},"funding":["https://github.com/sponsors/dinwwwh","https://opencollective.com/middleapi"],"license":"MIT","scripts":{"build":"unbuild","type:check":"tsc -b"},"version":"0.9.2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:65935932-a786-477f-bf9f-c34f45e704bf"}},"keywords":["standard-server","http","server","client","request","response","transport-agnostic","body-parser","validator","sse","server-sent-events","streaming","typescript"],"repository":{"url":"git+https://github.com/middleapi/standard-server.git","type":"git","directory":"packages/core"},"description":"The Standard Server contract: transport-agnostic request, response, body, and streaming types with body parsing rules, runtime validators, and SSE helpers shared by every adapter","directories":{},"maintainers":[{"name":"dinwwwh","email":"dinwwwh@gmail.com"}],"sideEffects":false,"dependencies":{"@standard-server/shared":"0.9.2"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_0.9.2_1789805759986_0.2649887684184582"}}},"time":{"created":"2026-09-06T08:27:39.102Z","modified":"2026-09-19T08:16:00.413Z","0.8.3":"2026-09-06T08:27:39.356Z","0.9.0":"2026-09-06T08:34:53.377Z","0.9.1":"2026-09-16T08:55:07.854Z","0.9.2":"2026-09-19T08:16:00.062Z"},"license":"MIT","keywords":["standard-server","http","server","client","request","response","transport-agnostic","body-parser","validator","sse","server-sent-events","streaming","typescript"],"repository":{"url":"git+https://github.com/middleapi/standard-server.git","type":"git","directory":"packages/core"},"description":"The Standard Server contract: transport-agnostic request, response, body, and streaming types with body parsing rules, runtime validators, and SSE helpers shared by every adapter","maintainers":[{"name":"dinwwwh","email":"dinwwwh@gmail.com"}],"readme":"# Standard Server\n\n<div align=\"center\">\n  <a href=\"https://codecov.io/gh/middleapi/standard-server\">\n    <img alt=\"codecov\" src=\"https://codecov.io/gh/middleapi/standard-server/branch/main/graph/badge.svg\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/@standard-server/core\">\n    <img alt=\"weekly downloads\" src=\"https://img.shields.io/npm/dw/%40standard-server%2Fcore?logo=npm\" />\n  </a>\n  <a href=\"https://app.codspeed.io/middleapi/standard-server?utm_source=badge\">\n    <img src=\"https://img.shields.io/endpoint?url=https://codspeed.io/badge.json\" alt=\"CodSpeed\" />\n  </a>\n  <a href=\"https://github.com/middleapi/standard-server/blob/main/LICENSE\">\n    <img alt=\"MIT License\" src=\"https://img.shields.io/github/license/middleapi/standard-server?logo=open-source-initiative\" />\n  </a>\n  <a href=\"https://discord.gg/TXEbwRBvQn\">\n    <img alt=\"Discord\" src=\"https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff\" />\n  </a>\n  <a href=\"https://deepwiki.com/middleapi/standard-server\">\n    <img src=\"https://deepwiki.com/badge.svg\" alt=\"Ask DeepWiki\">\n  </a>\n</div>\n\n`@standard-server/core` is the shared contract package for **Standard Server** — a unified interface for client-server communication across HTTP and message-based transports. It lets you keep handler and client code transport-agnostic by working with the same request, response, body, and streaming abstractions whether the transport is Fetch, Node.js HTTP, or a peer-style message channel.\n\nStandard Server ships as a small ecosystem of packages:\n\n| Package                                                                                                               | Description                                                                 |\n| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |\n| [`@standard-server/core`](https://github.com/middleapi/standard-server/blob/main/packages/core/README.md)             | The shared contract: types, body parsing rules, validators, and SSE helpers |\n| [`@standard-server/fetch`](https://github.com/middleapi/standard-server/blob/main/packages/fetch/README.md)           | Fetch API adapter for browsers, workers, and other Fetch-based runtimes     |\n| [`@standard-server/node`](https://github.com/middleapi/standard-server/blob/main/packages/node/README.md)             | Node.js HTTP and HTTP/2 adapter                                             |\n| [`@standard-server/fastify`](https://github.com/middleapi/standard-server/blob/main/packages/fastify/README.md)       | Fastify adapter built on the Node.js adapter                                |\n| [`@standard-server/aws-lambda`](https://github.com/middleapi/standard-server/blob/main/packages/aws-lambda/README.md) | AWS Lambda adapter with response streaming                                  |\n| [`@standard-server/peer`](https://github.com/middleapi/standard-server/blob/main/packages/peer/README.md)             | Message-based adapter for WebSocket, MessagePort, and custom transports     |\n| [`@standard-server/shared`](https://github.com/middleapi/standard-server/blob/main/packages/shared/README.md)         | Internal utilities shared across the ecosystem                              |\n\nThis package is the foundation of that model. It defines the request and response types every adapter converts to and from, the body parsing rules they all share, runtime validators, header and URL utilities, and event stream (SSE) helpers.\n\n## Request and response types\n\nThe package exposes four transport-agnostic shapes:\n\n| Export                 | Description                                                     |\n| ---------------------- | --------------------------------------------------------------- |\n| `StandardRequest`      | Eager request object with a parsed `body`                       |\n| `StandardLazyRequest`  | Request object with `resolveBody(hint?)` for lazy body parsing  |\n| `StandardResponse`     | Eager response object with a parsed `body`                      |\n| `StandardLazyResponse` | Response object with `resolveBody(hint?)` for lazy body parsing |\n\nSupporting primitives:\n\n| Export             | Description                                                   |\n| ------------------ | ------------------------------------------------------------- |\n| `StandardMethod`   | Common HTTP verbs plus any custom string value                |\n| `StandardUrl`      | A request URL that must start with `/` and exclude the origin |\n| `StandardHeaders`  | `Record<string, string \\| string[] \\| undefined>`             |\n| `StandardBodyHint` | Parsing hint for lazy body resolution                         |\n| `StandardBody`     | Shared body union used by requests and responses              |\n\nBy convention, adapters normalize headers to lowercase keys. `signal` is part of `StandardRequest` only and is used to propagate request cancellation.\n\n```ts\nimport type { StandardLazyRequest, StandardResponse } from '@standard-server/core'\n\nexport async function handle(request: StandardLazyRequest): Promise<StandardResponse> {\n  const body = await request.resolveBody()\n\n  return {\n    status: 200,\n    headers: { 'content-type': 'application/json' },\n    body: {\n      ok: true,\n      method: request.method,\n      url: request.url,\n      received: body,\n    },\n  }\n}\n```\n\n## Body types\n\n`StandardBodyHint` and `StandardBody` describe the shared body contract used across adapters:\n\n| Hint                | `StandardBody` value           | Typical content type                | Notes                                                 |\n| ------------------- | ------------------------------ | ----------------------------------- | ----------------------------------------------------- |\n| `json`              | `unknown`                      | `application/json`                  | Primitives, objects, and arrays                       |\n| `form-data`         | `FormData`                     | `multipart/form-data`               | Multipart form submissions                            |\n| `url-search-params` | `URLSearchParams`              | `application/x-www-form-urlencoded` | URL-encoded forms                                     |\n| `event-stream`      | `AsyncIteratorObject<unknown>` | `text/event-stream`                 | Server-Sent Events (SSE)                              |\n| `octet-stream`      | `ReadableStream<Uint8Array>`   | any                                 | Binary streaming                                      |\n| `file`              | `File`                         | any                                 | Fixed-size binary payloads for both `File` and `Blob` |\n| `none`              | `undefined`                    |                                     | Empty body                                            |\n\n### JSON body\n\nStandard Server treats primitive values, objects, and arrays as JSON.\n\n```ts\nimport type { StandardRequest } from '@standard-server/core'\n\nconst request: StandardRequest = {\n  method: 'POST',\n  url: '/submit',\n  headers: {},\n  body: { name: 'John Doe', email: 'john.doe@example.com' },\n}\n```\n\n### FormData and URLSearchParams body\n\nStandard Server treats [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) and [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) as form submissions.\n\n```ts\nimport type { StandardRequest } from '@standard-server/core'\n\nconst requestWithURLSearchParams: StandardRequest = {\n  method: 'POST',\n  url: '/submit',\n  headers: {},\n  body: new URLSearchParams({ name: 'John Doe', email: 'john.doe@example.com' }),\n}\n\nconst formData = new FormData()\nformData.append('name', 'John Doe')\nformData.append('file', new Blob(['Hello, World!'], { type: 'text/plain' }), 'hello.txt')\n\nconst requestWithFormData: StandardRequest = {\n  method: 'POST',\n  url: '/submit',\n  headers: {},\n  body: formData,\n}\n```\n\n> [!TIP]\n> HTML forms submit data as `application/x-www-form-urlencoded` or `multipart/form-data`, so these body types are especially helpful there.\n\n### File and Blob body\n\nStandard Server treats [File](https://developer.mozilla.org/en-US/docs/Web/API/File) and [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) as fixed-size binary payloads.\n\n> [!NOTE]\n> Since `File` extends `Blob`, `resolveBody` always returns a `File` when representing either `File` or `Blob` bodies.\n\n```ts\nimport type { StandardResponse } from '@standard-server/core'\n\nconst response: StandardResponse = {\n  status: 200,\n  headers: {\n    'content-disposition': [], // <- remove auto-set header\n  },\n  body: new File(['Hello, World!'], 'hello.txt', { type: 'text/plain' }),\n}\n```\n\nWhen sending a file or blob body, adapters automatically set the `content-length`, `content-type`, `content-disposition`, and `standard-server` headers based on the provided body. You can override any of them by explicitly providing a header value, or remove one entirely by assigning an empty array.\n\n### Event-stream body\n\nStandard Server uses [AsyncIteratorObject](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator) to represent an event stream body, and you can use `withEventMeta()` to attach additional [SSE event metadata](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format) to each emitted event.\n\n```ts\nimport type { StandardResponse } from '@standard-server/core'\nimport { ErrorEvent, withEventMeta } from '@standard-server/core'\n\nconst response: StandardResponse = {\n  status: 200,\n  headers: {},\n  async* body() {\n    yield withEventMeta(\n      { message: 'Hello, World!' },\n      { id: '1', retry: 3000, comments: ['hidden'] },\n    )\n\n    throw new ErrorEvent({ message: 'Something went wrong' })\n\n    return { message: 'This is the end of the stream' }\n  },\n}\n```\n\nEvents are interpreted as follows: `yield` emits a `message`, `throw` emits an `error`, and `return` emits a `close` event. Note that `close` does not cause [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) to close the connection because it is not part of the SSE specification. However, when using Standard Server for client-side streaming, `close` is treated as the end of the stream, so the connection is closed and no reconnection is attempted.\n\nFor explicit SSE encoding, decoding, and metadata handling, see the [Event-Stream Helpers](#event-stream-helpers) below.\n\n### Octet-stream body\n\nStandard Server uses [ReadableStream<Uint8Array>](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) to represent a binary streaming body.\n\n```ts\nimport type { StandardResponse } from '@standard-server/core'\n\nconst response: StandardResponse = {\n  status: 200,\n  headers: {\n    'content-type': 'application/octet-stream',\n  },\n  body: new ReadableStream<Uint8Array>({\n    start(controller) {\n      const encoder = new TextEncoder()\n      controller.enqueue(encoder.encode('Hello, World!'))\n      controller.close()\n    },\n  }),\n}\n```\n\nWhen sending a binary streaming body, adapters automatically set the `content-type` and `standard-server` headers. You can override `content-type` by providing an explicit header value, or remove it entirely by assigning an empty array.\n\n## How body parsing works\n\n> [!NOTE]\n> This section applies to the HTTP adapters (Fetch, Node.js, Fastify, AWS Lambda). It does not apply to the [peer adapter](https://github.com/middleapi/standard-server/blob/main/packages/peer/README.md#body-resolution), which identifies body types through its own message protocol — a different but fairly similar mechanism.\n\n`resolveBody(hint?)` on `StandardLazyRequest` and `StandardLazyResponse` resolves the body lazily — the underlying stream is only consumed once you call it. The `StandardBodyHint` that decides how the raw body is parsed comes from three places: an explicit `hint` argument, the `standard-server` header, or inference from the content headers.\n\n### The `standard-server` header\n\nA `StandardBody` is richer than what HTTP content headers can describe. `content-type` tells the receiver the _media type_ of the bytes, but not which `StandardBody` representation the sender intended:\n\n- A file upload can legitimately carry `content-type: application/json`. Without more information, the receiver would parse it into a JSON value when the sender meant a `File` to be stored as-is.\n- A fixed-size binary payload (`file`) and a binary stream (`octet-stream`) can share any content type. Telling them apart otherwise depends on `content-length`, which proxies may rewrite and some runtimes drop when the payload is empty.\n\nThe `standard-server` header closes this gap. It carries the sender's `StandardBodyHint` verbatim — `json`, `form-data`, `url-search-params`, `event-stream`, `octet-stream`, `file`, or `none` — so the receiver reconstructs exactly the body representation the sender had.\n\nAdapters set the header automatically for the ambiguous body types: a `Blob` or `File` body is sent with `standard-server: file`, and a `ReadableStream` body with `standard-server: octet-stream`, alongside the usual content headers. A header you set yourself always wins, and assigning an empty array removes it entirely. For the other body types, the content headers are enough, so adapters clear it.\n\nThe header is optional: when it is absent or invalid, the receiver falls back to content-header inference, so plain HTTP clients work as-is. Just set the header yourself whenever the content type alone could be misread:\n\n```ts\nconst response = await fetch('/upload', {\n  method: 'POST',\n  headers: {\n    'content-type': 'application/json',\n    'standard-server': 'file', // <- keep the payload a File on the server\n  },\n  body: new Blob(['{\"message\": \"Hello, world!\"}'], { type: 'application/json' }),\n})\n```\n\n### Resolution order\n\nThe hint is chosen in this order:\n\n1. **Explicit `hint` argument.** If you pass a hint to `resolveBody(hint)`, it always wins.\n2. **The `standard-server` header.** If present and holding a valid hint value, it is used verbatim. Unknown values are ignored.\n3. **Content-header inference:**\n   1. No `content-type`, and `content-length` absent or `0` → `none`.\n   2. A common `content-type` → `application/json` parses as `json`, `multipart/form-data` as `form-data`, `application/x-www-form-urlencoded` as `url-search-params`, and `text/event-stream` as `event-stream`. Media type casing and parameters such as `; charset=utf-8` are ignored.\n   3. A `content-disposition` carrying a filename, or any `content-length` → `file`.\n   4. Anything else → `octet-stream`.\n\nThis resolution is implemented once in this package as `resolveStandardBodyHint(headers)` and shared by every HTTP adapter, so the same body parses the same way regardless of which HTTP transport carried it:\n\n```ts\nimport { resolveStandardBodyHint } from '@standard-server/core'\n\nresolveStandardBodyHint({ 'content-type': 'application/json' })\n// 'json'\n\nresolveStandardBodyHint({\n  'content-type': 'application/json',\n  'standard-server': 'file',\n})\n// 'file'\n\nresolveStandardBodyHint({})\n// 'none'\n```\n\nUse it when building a custom adapter, or when you need to know how a body will parse without consuming it.\n\n## Utilities\n\nThe package also exports a small set of helpers for common header and URL operations.\n\n### Content-Disposition helpers\n\nUse `generateContentDisposition()` to produce a safe `Content-Disposition` value and `getFilenameFromContentDisposition()` to read a filename back from an existing header.\n\n```ts\nimport {\n  generateContentDisposition,\n  getFilenameFromContentDisposition,\n} from '@standard-server/core'\n\nconst disposition = generateContentDisposition('report \"Q2\".csv')\n// inline; filename=\"report \\\"Q2\\\".csv\"; filename*=utf-8''report%20%22Q2%22.csv\n\nconst filename = getFilenameFromContentDisposition(disposition)\n// 'report \"Q2\".csv'\n```\n\n`generateContentDisposition()` preserves an ASCII-safe `filename=\"...\"` value and also emits `filename*=` for UTF-8 aware clients.\n\n### Header helpers\n\n`mergeStandardHeaders()` combines two `StandardHeaders` objects while preserving duplicate values, and `flattenStandardHeader()` turns a single header value into a plain string when needed.\n\n```ts\nimport {\n  flattenStandardHeader,\n  mergeStandardHeaders,\n} from '@standard-server/core'\n\nconst headers = mergeStandardHeaders(\n  { 'accept': 'application/json', 'set-cookie': ['a=1'] },\n  { 'set-cookie': 'b=2', 'vary': 'accept', 'warning': undefined },\n)\n// {\n//   accept: 'application/json',\n//   'set-cookie': ['a=1', 'b=2'],\n//   vary: 'accept',\n// }\n\nconst cookieHeader = flattenStandardHeader(headers['set-cookie'])\n// 'a=1, b=2'\n```\n\n### URL parsing\n\n`parseStandardUrl()` splits a `StandardUrl` into `[pathname, search, hash]` without requiring a full origin.\n\n```ts\nimport { parseStandardUrl } from '@standard-server/core'\n\nconst [pathname, search, hash] = parseStandardUrl('/users/123?tab=settings#profile')\n// pathname => '/users/123'\n// search => '?tab=settings'\n// hash => '#profile'\n```\n\n## Validators\n\nRuntime type guards are useful when requests or responses cross process, transport, or message boundaries.\n\n| Export                 | Checks                                                 |\n| ---------------------- | ------------------------------------------------------ |\n| `isStandardMethod()`   | Any string value                                       |\n| `isStandardUrl()`      | A string starting with `/`                             |\n| `isStandardHeaders()`  | Object values are `string`, `string[]`, or `undefined` |\n| `isStandardRequest()`  |                                                        |\n| `isStandardResponse()` |                                                        |\n\n```ts\nimport { isStandardRequest } from '@standard-server/core'\n\nexport function expectStandardRequest(input: unknown) {\n  if (!isStandardRequest(input)) {\n    throw new TypeError('Expected a StandardRequest-compatible value')\n  }\n\n  return input\n}\n```\n\n## Event-Stream Helpers\n\nUse Event-Stream Helpers when you need explicit SSE encoding, decoding, or metadata handling.\n\n### Message types and codecs\n\nThe event-stream helpers include:\n\n- `EventMeta` for `id`, `retry`, and `comments`\n- `EventStreamMessage` for complete SSE messages\n- `encodeEventStreamMessage()` and `decodeEventStreamMessage()` for single-message codec operations\n- `EventStreamDecoder` and `EventStreamDecoderStream` for chunked stream decoding\n\n```ts\nimport {\n  decodeEventStreamMessage,\n  encodeEventStreamMessage,\n} from '@standard-server/core'\n\nconst encoded = encodeEventStreamMessage({\n  comments: ['bootstrap'],\n  event: 'message',\n  id: '42',\n  retry: 3000,\n  data: 'hello\\nworld',\n})\n\nconst decoded = decodeEventStreamMessage(encoded)\n// {\n//   comments: ['bootstrap'],\n//   event: 'message',\n//   id: '42',\n//   retry: 3000,\n//   data: 'hello\\nworld',\n// }\n```\n\nFor streaming decode, pipe text chunks through `EventStreamDecoderStream`:\n\n```ts\nimport { EventStreamDecoderStream } from '@standard-server/core'\n\nconst messages = response.body!\n  .pipeThrough(new TextDecoderStream())\n  .pipeThrough(new EventStreamDecoderStream())\n```\n\n### Iterator metadata helpers\n\n`StandardBody` uses async iterators for event-stream bodies. To attach SSE metadata to a yielded value without changing its visible shape, use `withEventMeta()`.\n\n```ts\nimport type { StandardResponse } from '@standard-server/core'\nimport { getEventMeta, unwrapEvent, withEventMeta } from '@standard-server/core'\n\nconst event = withEventMeta(\n  { message: 'hello' },\n  { id: '1', retry: 3000, comments: ['bootstrap'] },\n)\n\nconst [data, meta] = unwrapEvent(event)\n// data => { message: 'hello' }\n// meta => { id: '1', retry: 3000, comments: ['bootstrap'] }\n\nconst extractedMeta = getEventMeta(event)\n// { id: '1', retry: 3000, comments: ['bootstrap'] }\n\nconst response: StandardResponse = {\n  status: 200,\n  headers: {},\n  async* body() {\n    yield event\n  },\n}\n```\n\n> [!WARNING]\n> Metadata is validated before it is attached: `id`, `event`, and comments must not contain line breaks, and `retry` must be a non-negative integer.\n\n### Errors and low-level assertions\n\nThe package also exports:\n\n- `EventStreamEncoderError` for invalid outbound SSE messages\n- `EventStreamDecoderError` for incomplete or invalid inbound stream decoding\n- `ErrorEvent` for wrapping structured event-stream error payloads in an `Error`\n- `assertEventStreamMessageId()`, `assertEventStreamMessageName()`, `assertEventStreamMessageRetry()`, and `assertEventStreamMessageComment()` for low-level validation when building custom SSE tooling\n\n```ts\nimport { ErrorEvent } from '@standard-server/core'\n\nconst error = new ErrorEvent(\n  { code: 'E_STREAM', detail: 'Connection lost' },\n  { message: 'stream error' },\n)\n\nerror.message\n// 'stream error'\n\nerror.data\n// { code: 'E_STREAM', detail: 'Connection lost' }\n```\n\n## Learn more\n\nFor transport-specific quick-starts and options, see the adapter documentation: [Fetch](https://github.com/middleapi/standard-server/blob/main/packages/fetch/README.md) · [Node.js](https://github.com/middleapi/standard-server/blob/main/packages/node/README.md) · [Fastify](https://github.com/middleapi/standard-server/blob/main/packages/fastify/README.md) · [AWS Lambda](https://github.com/middleapi/standard-server/blob/main/packages/aws-lambda/README.md) · [Peer](https://github.com/middleapi/standard-server/blob/main/packages/peer/README.md)\n\n## Sponsors\n\nLike what we build over at [middleapi](https://github.com/middleapi)? You can help keep it going through [GitHub Sponsors](https://github.com/sponsors/dinwwwh) or [Open Collective](https://opencollective.com/middleapi). Every bit helps! 🚀\n\n<table>\n  <tr>\n   <td width=\"2000\"><a href=\"https://screenshotone.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener\" title=\"The screenshot API for developers\"><img src=\"https://avatars.githubusercontent.com/u/97035603?v=4\" width=\"64\" align=\"left\" hspace=\"12\" alt=\"ScreenshotOne.com\"/><b>ScreenshotOne.com</b></a><br /><sub>The screenshot API for developers</sub></td>\n  </tr>\n  <tr>\n   <td width=\"2000\"><a href=\"https://yuzu.health/careers?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"We&#39;re hiring NYC based engineers\"><img src=\"https://avatars.githubusercontent.com/u/102488956?v=4\" width=\"64\" align=\"left\" hspace=\"12\" alt=\"Yuzu\"/><b>Yuzu</b></a><br /><sub>We&#39;re hiring NYC based engineers</sub></td>\n  </tr>\n  <tr>\n   <td width=\"2000\"><a href=\"https://misskey.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Decentralized microblogging SNS born on Earth\"><img src=\"https://github.com/MisskeyIO.png\" width=\"64\" align=\"left\" hspace=\"12\" alt=\"MisskeyHQ\"/><b>MisskeyHQ</b></a><br /><sub>Decentralized microblogging SNS born on Earth</sub></td>\n  </tr>\n</table>\n\n### Special Sponsors\n\n<table>\n  <tr>\n   <td align=\"center\"><a href=\"http://twitter.com/rauchg?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Guillermo Rauch\"><img src=\"https://avatars.githubusercontent.com/u/13041?u=1ee8d111657cdd02ff6d253df00978d17ee6d722&amp;v=4\" width=\"279\" alt=\"Guillermo Rauch\"/><br />Guillermo Rauch</a></td>\n  </tr>\n</table>\n\n### Organization Sponsors\n\n<table>\n  <tr>\n   <td align=\"center\"><a href=\"https://lnmarkets.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"LN Markets\"><img src=\"https://avatars.githubusercontent.com/u/70597625?v=4\" width=\"167\" alt=\"LN Markets\"/><br />LN Markets</a></td>\n  </tr>\n</table>\n\n### Sponsors\n\n<table>\n  <tr>\n   <td align=\"center\"><a href=\"https://github.com/hrmcdonald?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Reece McDonald\"><img src=\"https://avatars.githubusercontent.com/u/39349270?v=4\" width=\"139\" alt=\"Reece McDonald\"/><br />Reece McDonald</a></td>\n   <td align=\"center\"><a href=\"https://soymilk.party/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"あわわわとーにゅ\"><img src=\"https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&amp;v=4\" width=\"139\" alt=\"あわわわとーにゅ\"/><br />あわわわとーにゅ</a></td>\n   <td align=\"center\"><a href=\"https://github.com/nicognaW?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"nk\"><img src=\"https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&amp;v=4\" width=\"139\" alt=\"nk\"/><br />nk</a></td>\n   <td align=\"center\"><a href=\"https://supastarter.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"supastarter\"><img src=\"https://avatars.githubusercontent.com/u/110960143?v=4\" width=\"139\" alt=\"supastarter\"/><br />supastarter</a></td>\n   <td align=\"center\"><a href=\"https://github.com/divmgl?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Dexter Miguel\"><img src=\"https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&amp;v=4\" width=\"139\" alt=\"Dexter Miguel\"/><br />Dexter Miguel</a></td>\n   <td align=\"center\"><a href=\"https://github.com/herrfugbaum?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"herrfugbaum\"><img src=\"https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&amp;v=4\" width=\"139\" alt=\"herrfugbaum\"/><br />herrfugbaum</a></td>\n  </tr>\n  <tr>\n   <td align=\"center\"><a href=\"https://laststance.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Ryota Murakami\"><img src=\"https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&amp;v=4\" width=\"139\" alt=\"Ryota Murakami\"/><br />Ryota Murakami</a></td>\n   <td align=\"center\"><a href=\"https://cra.mr/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"David Cramer\"><img src=\"https://avatars.githubusercontent.com/u/23610?v=4\" width=\"139\" alt=\"David Cramer\"/><br />David Cramer</a></td>\n   <td align=\"center\"><a href=\"https://valerii15298.github.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Valerii Petryniak\"><img src=\"https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&amp;v=4\" width=\"139\" alt=\"Valerii Petryniak\"/><br />Valerii Petryniak</a></td>\n   <td align=\"center\"><a href=\"https://letstri.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Valerii Strilets\"><img src=\"https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&amp;v=4\" width=\"139\" alt=\"Valerii Strilets\"/><br />Valerii Strilets</a></td>\n   <td align=\"center\"><a href=\"https://blacklight.sh/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Kyle Mistele\"><img src=\"https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&amp;v=4\" width=\"139\" alt=\"Kyle Mistele\"/><br />Kyle Mistele</a></td>\n   <td align=\"center\"><a href=\"https://github.com/christ12938?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"christ12938\"><img src=\"https://avatars.githubusercontent.com/u/25758598?v=4\" width=\"139\" alt=\"christ12938\"/><br />christ12938</a></td>\n  </tr>\n  <tr>\n   <td align=\"center\"><a href=\"https://github.com/Ryanjso?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Ryan Soderberg\"><img src=\"https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4\" width=\"139\" alt=\"Ryan Soderberg\"/><br />Ryan Soderberg</a></td>\n   <td align=\"center\"><a href=\"https://github.com/itigoore01?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"shota\"><img src=\"https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4\" width=\"139\" alt=\"shota\"/><br />shota</a></td>\n   <td align=\"center\"><a href=\"https://github.com/ellis-driscoll?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Ellis Driscoll\"><img src=\"https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&amp;v=4\" width=\"139\" alt=\"Ellis Driscoll\"/><br />Ellis Driscoll</a></td>\n   <td align=\"center\"><a href=\"https://github.com/hoangbn?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Hoang Nguyen\"><img src=\"https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&amp;v=4\" width=\"139\" alt=\"Hoang Nguyen\"/><br />Hoang Nguyen</a></td>\n   <td align=\"center\"><a href=\"https://opencollective.com/guest-ac41de3b?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Orestis Ioannou\"><img src=\"https://images.opencollective.com/guest-ac41de3b/avatar/460.png\" width=\"139\" alt=\"Orestis Ioannou\"/><br />Orestis Ioannou</a></td>\n   <td align=\"center\"><a href=\"https://automatio.ai/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Stefan Smiljkovic\"><img src=\"https://avatars.githubusercontent.com/u/1984909?u=b7bf5bc40ed49df3c22f69d2da7b8d78709c49ed&amp;v=4\" width=\"139\" alt=\"Stefan Smiljkovic\"/><br />Stefan Smiljkovic</a></td>\n  </tr>\n</table>\n\n### Backers\n\n<table>\n  <tr>\n   <td align=\"center\"><a href=\"https://github.com/rhinodavid?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"David Walsh\"><img src=\"https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&amp;v=4\" width=\"119\" alt=\"David Walsh\"/><br />David Walsh</a></td>\n   <td align=\"center\"><a href=\"https://github.com/IPv4Addr?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"IPv4Addr\"><img src=\"https://avatars.githubusercontent.com/u/100147665?u=59996b72f69bb53063cb7e9ff8b8f898616cd94d&amp;v=4\" width=\"119\" alt=\"IPv4Addr\"/><br />IPv4Addr</a></td>\n   <td align=\"center\"><a href=\"https://robbevaes.be/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Robbe Vaes\"><img src=\"https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&amp;v=4\" width=\"119\" alt=\"Robbe Vaes\"/><br />Robbe Vaes</a></td>\n   <td align=\"center\"><a href=\"https://github.com/aidansunbury?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Aidan Sunbury\"><img src=\"https://avatars.githubusercontent.com/u/64103161?v=4\" width=\"119\" alt=\"Aidan Sunbury\"/><br />Aidan Sunbury</a></td>\n   <td align=\"center\"><a href=\"https://github.com/soonoo?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"soonoo\"><img src=\"https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&amp;v=4\" width=\"119\" alt=\"soonoo\"/><br />soonoo</a></td>\n   <td align=\"center\"><a href=\"https://kevinporten.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Kevin Porten\"><img src=\"https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&amp;v=4\" width=\"119\" alt=\"Kevin Porten\"/><br />Kevin Porten</a></td>\n   <td align=\"center\"><a href=\"https://github.com/pumpkinlink?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Denis\"><img src=\"https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&amp;v=4\" width=\"119\" alt=\"Denis\"/><br />Denis</a></td>\n  </tr>\n  <tr>\n   <td align=\"center\"><a href=\"https://github.com/christopher-kapic?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Christopher Kapic\"><img src=\"https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&amp;v=4\" width=\"119\" alt=\"Christopher Kapic\"/><br />Christopher Kapic</a></td>\n   <td align=\"center\"><a href=\"http://ballingt.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Tom Ballinger\"><img src=\"https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&amp;v=4\" width=\"119\" alt=\"Tom Ballinger\"/><br />Tom Ballinger</a></td>\n   <td align=\"center\"><a href=\"https://lee-sam.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Sam\"><img src=\"https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&amp;v=4\" width=\"119\" alt=\"Sam\"/><br />Sam</a></td>\n   <td align=\"center\"><a href=\"https://github.com/Titoine?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Titoine\"><img src=\"https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&amp;v=4\" width=\"119\" alt=\"Titoine\"/><br />Titoine</a></td>\n   <td align=\"center\"><a href=\"https://rigtch.fm/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Igor Makowski\"><img src=\"https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&amp;v=4\" width=\"119\" alt=\"Igor Makowski\"/><br />Igor Makowski</a></td>\n   <td align=\"center\"><a href=\"https://blog.cwang.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"hanayashiki\"><img src=\"https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&amp;v=4\" width=\"119\" alt=\"hanayashiki\"/><br />hanayashiki</a></td>\n   <td align=\"center\"><a href=\"https://dubinets.io/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Lev Dubinets\"><img src=\"https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&amp;v=4\" width=\"119\" alt=\"Lev Dubinets\"/><br />Lev Dubinets</a></td>\n  </tr>\n  <tr>\n   <td align=\"center\"><a href=\"https://kellychan.im/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Kelly Peilin Chan\"><img src=\"https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4\" width=\"119\" alt=\"Kelly Peilin Chan\"/><br />Kelly Peilin Chan</a></td>\n   <td align=\"center\"><a href=\"https://guyariely.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Guy Ariely\"><img src=\"https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&amp;v=4\" width=\"119\" alt=\"Guy Ariely\"/><br />Guy Ariely</a></td>\n   <td align=\"center\"><a href=\"https://paulsenon.com/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"PaulSenon\"><img src=\"https://avatars.githubusercontent.com/u/19531087?u=6385741eb91d200b8c513ec6045482e301767ca6&amp;v=4\" width=\"119\" alt=\"PaulSenon\"/><br />PaulSenon</a></td>\n   <td align=\"center\"><a href=\"https://piscis.dev/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Alex\"><img src=\"https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&amp;v=4\" width=\"119\" alt=\"Alex\"/><br />Alex</a></td>\n   <td align=\"center\"><a href=\"https://opensource.gubanov.eu/?ref=middleapi&amp;utm_source=middleapi&amp;utm_medium=sponsor\" target=\"_blank\" rel=\"noopener sponsored\" title=\"Andrey Gubanov\"><img src=\"https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&amp;v=4\" width=\"119\" alt=\"Andrey Gubanov\"/><br />Andrey Gubanov</a></td>\n  </tr>\n</table>\n\nWith thanks to [36 past sponsors](https://htmlpreview.github.io/?https://github.com/middleapi/static/blob/main/sponsors.svg) who helped get us here.\n\n## License\n\nDistributed under the MIT License. See [LICENCE](https://github.com/middleapi/standard-server/blob/main/LICENCE) for more information.\n","readmeFilename":""}