@apeleghq/http-media-type-negotiator

中文文档
1.0.8发布于 2025/10/14ISCTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 7477

RFC-aware HTTP media type negotiator - parses and normalises Accept headers and media types (RFC 9110), supports q-value ranking, wildcard matching, and a permissive mode for real-world headers.

原始使用文档
文档目录11 节
  1. 🚀 Features
  2. 💻 Installation
  3. 📚 Usage
  4. One-shot negotiation
  5. Reusable negotiator (recommended for repeated calls)
  6. Permissive mode
  7. Compatibility with negotiator
  8. ⚙️ Behaviour notes
  9. ✅ Recommended usage pattern
  10. 🤝 Contributing
  11. 📜 License

HTTP Media Type Negotiator

NPM Downloads


🚀 Features

  • No runtime dependencies.
  • Runtime and framework agnostic.
  • Negotiates HTTP media types (Accept header) against server-supported types following RFC 9110 §5.6.
  • Parses and normalises media types and Accept headers with optional permissive mode to tolerate common real-world deviations.
  • Supports q-value parsing and ranking.
  • Tie-breaking by specificity, shared parameters, then server order for deterministic results.
  • Exposes both a reusable factory for repeated negotiation and a one-shot convenience function.
  • It also exposes convenience functions (also used internally) for:
    • Parsing media types (parseMediaType)
    • Normalising said media types (normaliseMediaType)
    • Parsing Accept heades (parseAcceptHeader)

💻 Installation

Install from npm or yarn:

npm install @apeleghq/http-media-type-negotiator

or

yarn add @apeleghq/http-media-type-negotiator

📚 Usage

One-shot negotiation

Use the convenience function when you just need to negotiate once:

import { negotiateMediaType } from '@apeleghq/http-media-type-negotiator';

const available = [
  'text/plain; charset=utf-8',
  'application/json',
];

const best = negotiateMediaType(available, 'text/*;q=0.9, application/json;q=0.8');
// best -> 'text/plain; charset=utf-8'

Create a negotiator once for a fixed set of server-supported media types to avoid reparsing:

import { negotiateMediaTypeFactory } from '@apeleghq/http-media-type-negotiator';

const available = [
  'text/plain; charset=utf-8',
  'application/json',
];

const negotiate = negotiateMediaTypeFactory(available);

// Later, for each request:
const best1 = negotiate('application/json');
const best2 = negotiate('text/*;q=0.9, application/json;q=0.8');

Permissive mode

Pass the optional permissive flag to tolerate non-RFC-compliant inputs (extra whitespace, empty parameter values, flag parameters like ;foo, and truncated quoted values at EOF):

const best = negotiate(acceptHeader, true); // permissive parsing

Compatibility with negotiator

An API that emulates the negotiator package is available via the @apeleghq/http-media-type-negotiator/compat/Negotiator export.

The mediaType and mediaTypes interfaces are exposed, although they don't behave identically to those in negotiator:

  • mediaTypes will return at most a single media type if the availableMediaTypes parameter is provided.
  • The negotiation algorithm may produce different results.

⚙️ Behaviour notes

  • Returned strings are the original server-provided strings from the availableMediaTypes array.
  • Q-values are parsed and converted to integer weights between 0 and 1000 (1.0 → 1000). Entries with q=0 are ignored.
  • Matching supports exact type/subtype, type with wildcard subtype (e.g. text/*), and */*.
  • When multiple acceptable ranges tie on q, the negotiator prefers:
    1. More specific type/subtype (non-*),
    2. Media-range that shares the most non-q parameters with the available type,
    3. Server order (the order of available types provided).
  • The parser returns substrings for Accept entries and reparses them into structured media types internally; this keeps the implementation allocation-light.
  • Parameter values are not normalised and evaluated as exact matches (meaning case-sensitively).
  • If negotiating repeatedly for the same server-supported types, use negotiateMediaTypeFactory once and reuse the returned function to avoid reparsing available types.
  • Normalise case if you need canonical string comparisons beyond what the negotiator provides.

🤝 Contributing

Contributions welcome. Please open issues or pull requests on the repository. Consider adding unit tests for edge cases and performance benchmarks if you change parsing behaviour.

📜 License

This project is released under the ISC license. See the LICENSE file for details.

版本与发布记录

@apeleghq/http-media-type-negotiator 共发布 9 个版本,首次发布于 2025/09/18;过去 12 个月发布了 0 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.8latest2025/10/141.1 年前
1.0.72025/10/131.1 年前
1.0.62025/10/121.1 年前
1.0.52025/10/031.1 年前
1.0.42025/10/031.1 年前
1.0.32025/09/231.1 年前

关于 @apeleghq/http-media-type-negotiator 的常见问题

@apeleghq/http-media-type-negotiator 是什么?

RFC-aware HTTP media type negotiator - parses and normalises Accept headers and media types (RFC 9110), supports q-value ranking, wildcard matching, and a permissive mode for real-world headers.

如何安装 @apeleghq/http-media-type-negotiator?

在项目目录运行 npm install @apeleghq/http-media-type-negotiator,或使用 pnpm add / yarn add / bun add。

@apeleghq/http-media-type-negotiator 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@apeleghq/http-media-type-negotiator 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@apeleghq/http-media-type-negotiator 可以商用吗?

@apeleghq/http-media-type-negotiator 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@apeleghq/http-media-type-negotiator 的下载量有多少?

根据 npm 官方下载统计,@apeleghq/http-media-type-negotiator 在 2026/10/06 – 2026/11/04 这 30 天内被下载 7,477 次,日均约 249 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@apeleghq/http-media-type-negotiator 还在维护吗?

最新版本 1.0.8 发布于 2025/10/14(1.1 年前);至今共发布 9 个版本,其中过去 12 个月发布了 0 个;首次发布于 2025/09/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。