Structured Headers
structured-headers is a JavaScript/TypeScript library providing a robust parser and serializer for HTTP Structured Field Values (RFC9651 and RFC8941). This specification standardizes complex HTTP header values, including lists, dictionaries, numbers, booleans, binary data (ByteSequences), timestamps, and Unicode strings (Display Strings). The current stable version is 2.0.2. New major versions are typically released to align with updates to the underlying RFCs, such as v2.0.0 which added support for RFC9651's new `Date` and `Display String` types. Patches address bug fixes and dependency updates. Key differentiators include its TypeScript foundation, shipping both ESM and CommonJS builds (though ESM is primary since v2), zero runtime dependencies, and an extensive test suite comprising 2805 unit tests largely sourced from the official HTTP Working Group. The library prioritizes strict RFC compliance, returning data structures that precisely mirror the specification, which can sometimes result in more complex types than developers might initially expect.
Common errors
-
ERR_REQUIRE_ESM: require() of ES Module /path/to/node_modules/structured-headers/dist/index.js not supported. Consider one of the following options to enable ESM support:
cause Attempting to import `structured-headers` using `require()` in a CommonJS module after upgrading to v2.0.0 or later.fixUpdate your import statements to use ES Modules syntax (`import { parseItem } from 'structured-headers';`). If in Node.js, ensure your package.json has `"type": "module"` or your file uses the `.mjs` extension. -
TypeError: Cannot read properties of undefined (reading 'buffer') when processing binary data.
cause Attempting to use `ByteSequence` objects or an outdated binary data format as input for serialization, or expecting `ByteSequence` output from parsing after upgrading to v2.0.0.fixAll binary data input for serialization and output from parsing is now `ArrayBuffer`. Ensure your code converts any `ByteSequence` instances to `ArrayBuffer` before passing them to serializer functions, and updates consumption of parsed binary data to handle `ArrayBuffer`.
Warnings
- breaking Since v2.0.0, the library has converted entirely to ES Modules (ESM). Attempts to `require()` the package in a CommonJS context will result in a module resolution error. Additionally, Node.js 18 or higher is now required.
- breaking In v2.0.0, the internal representation and API for binary data changed from a custom `ByteSequence` object to the standard `ArrayBuffer`. This affects how binary data is consumed and provided.
- gotcha Due to JavaScript's number type behavior, the library cannot differentiate between `1.0` and `1` during serialization. This means that if the specification strictly requires `1.0`, the library will output `1`, which is a known deviation from the official test suite.
- gotcha JavaScript's default rounding behavior differs slightly from the Structured Headers specification, specifically for values like `0.0025`. JavaScript typically rounds to `0.003`, while the spec suggests rounding to the nearest even number (`0.002`).
- gotcha The library prioritizes strict RFC compliance, returning the _exact_ data structures suggested by the specification. This can result in complex nested types (e.g., `[BareItem, Map<string, BareItem>]` for an Item) which might require careful destructuring or type handling.
Install
-
npm install structured-headers -
yarn add structured-headers -
pnpm add structured-headers
Imports
- parseItem
const parseItem = require('structured-headers');import { parseItem } from 'structured-headers'; - parseList
const parseList = require('structured-headers');import { parseList } from 'structured-headers'; - parseDictionary
import { parseDictionary } from 'structured-headers';
Quickstart
import { parseItem, parseList, parseDictionary } from 'structured-headers';
// Parsing an 'Item' header
const itemHeader = '"Hello world"; a="5", @1686634251, :RE0gbWUgZm9yIGEgZnJlZSBjb29raWU=:';
console.log('Parsed Item:', parseItem('"Hello world"; a="5"'));
console.log('Parsed Date Item:', parseItem('@1686634251'));
console.log('Parsed Binary Item:', parseItem(':RE0gbWUgZm9yIGEgZnJlZSBjb29raWU=:'));
// Parsing a 'List' header
const listHeader = 'sometoken; param1; param2=hi, 42, (innerlistitem1 innerlistitem2)';
console.log('Parsed List:', JSON.stringify(parseList(listHeader), null, 2));
// Parsing a 'Dictionary' header
const dictHeader = 'fn="evert", ln="pot", coffee=?1, foo=(1 2 3)';
console.log('Parsed Dictionary:', JSON.stringify(Object.fromEntries(parseDictionary(dictHeader)), null, 2));