Files
2026-05-27 23:47:53 +01:00

184 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# @suaveplan/cbor - RFC 8949 CBOR encoder/decoder + RFC 8742 sequences + RFC 9052 COSE bridge + RFC 8392 CWT + RFC 8610 CDDL — zero browser/Node deps
## Summary
RFC 8949 (CBOR) encoder + decoder, RFC 8742 (CBOR Sequences), pull-style
streaming decoder (`AsyncIterable<Uint8Array>` / `ReadableStream<Uint8Array>`),
RFC 9052 §7 `COSE_Key` ↔ JWK round-trip + IANA algorithm bridge,
deterministic-encoding shortcut, RFC 8949 §8 diagnostic notation, tag
registry with IANA built-in handlers, and a strict §5.1 well-formedness
predicate. Universal — runs unmodified in Bun, Node, Deno, and the
browser. Zero browser/Node deps.
> **Wave 1 status.** This package is the foundational codec layer. Larger
> capabilities authored in the design proposal —
> COSE structures (RFC 9052 §4–§6), CWT (RFC 8392), CDDL (RFC 8610), and the
> `ChunkDecoder` partial-item streaming surface — are scoped IN and queued
> as follow-up waves on top of this codec.
<!-- begin:auto-docs -->
## Documentation tree
- [ast](./src/cddl/ast.md) — Typed AST shapes per RFC 8610 §3 — the contract between the parser and the validator (and any future code generator). E…
- [lexer](./src/cddl/lexer.md) — CDDL tokenizer per RFC 8610 §3 ABNF grammar. Reads a CDDL source string and emits a sequence of `Token` objects termina…
- [parser](./src/cddl/parser.md) — CDDL parser per RFC 8610 §3 grammar. Consumes the token stream from the `tokenize` function and produces a typed AST (`…
- [validate](./src/cddl/validate.md) — Walk a decoded CBOR value against a parsed CDDL schema and report the first mismatch (with a JSON-pointer-like path). T…
- [alg-map](./src/cose/alg-map.md) — Bridge between IANA COSE Algorithm identifiers (`CoseAlg` literal strings or the equivalent numeric labels from RFC 905…
- [cose-key](./src/cose/cose-key.md) — Decodes and encodes RFC 9052 §7 `COSE_Key` structures. The decoder maps an RFC-encoded CBOR map onto a typed discrimina…
- [encrypt](./src/cose/encrypt.md) — `COSE_Encrypt` (RFC 9052 §5.1) — multi-recipient AEAD-encrypted COSE message in CBOR tag 96. Each recipient holds its o…
- [encrypt0](./src/cose/encrypt0.md) — `COSE_Encrypt0` (RFC 9052 §5.2) — single-recipient AEAD-encrypted COSE message in CBOR tag 16. Wraps AES-256-GCM and Ch…
- [headers](./src/cose/headers.md) — Typed `CoseHeader` map shape covering RFC 9052 §3.1 + IANA COSE Header Parameters (alg, crit, content type, kid, IV, Pa…
- [jwk](./src/cose/jwk.md) — Round-trip converter between RFC 9052 `COSE_Key` instances and RFC 7517 JWK shapes. WebAuthn attestation flows often ne…
- [mac](./src/cose/mac.md) — `COSE_Mac` (RFC 9052 §6.1) — multi-recipient MAC message in CBOR tag 97. Each recipient gets a wrapped copy of the cont…
- [mac0](./src/cose/mac0.md) — `COSE_Mac0` (RFC 9052 §6.2) — single-recipient MAC message in CBOR tag 17. Used for symmetric-key authentication of CWT…
- [sig-structure](./src/cose/sig-structure.md) — Builders for the canonical input to COSE signature, MAC, and AEAD computations per RFC 9052 §4.4 / §6.3 / §5.3. Every s…
- [sign](./src/cose/sign.md) — `COSE_Sign` (RFC 9052 §4.1) — multi-signer COSE message in CBOR tag 98. Use when a payload needs to be co-signed by mul…
- [sign1](./src/cose/sign1.md) — `COSE_Sign1` (RFC 9052 §4.2) — single-signer COSE message in CBOR tag 18. WebAuthn attestation, COSE-signed firmware, a…
- [claims](./src/cwt/claims.md) — Encode and decode RFC 8392 CBOR Web Token claim sets. The seven IANA- registered claims (`iss`, `sub`, `aud`, `exp`, `n…
- [verify](./src/cwt/verify.md) — End-to-end CWT verification: parse the COSE wrapper, verify the signature or MAC, decode the claim set, and check the s…
- [decoder](./src/decoder/decoder.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - half-float — Decodes 2 big-endian bytes representin…
- [decoder](./src/decoder/decoder.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - half-float — Decodes 2 big-endian bytes representin…
- [half-float](./src/decoder/half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
- [well-formed](./src/decoder/well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - half-float — Encodes a JavaScript `number` as IEEE……
- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - half-float — Encodes a JavaScript `number` as IEEE……
- [half-float](./src/encoder/half-float.md) — Encodes a JavaScript `number` as IEEE 754 binary16 (CBOR major 7 / value 25) when the round-trip is exact, and otherwis…
- [errors](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [error-codes](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
- [chunk-decoder](./src/streaming/chunk-decoder.md) — Partial-item streaming decoder. While `PullDecoder` yields one whole CBOR item at a time (waiting until each item is fu…
- [pull-decoder](./src/streaming/pull-decoder.md) — `PullDecoder` is a pull-style streaming decoder over an `AsyncIterable<Uint8Array>` or `ReadableStream<Uint8Array>`. Ea…
- [builtin](./src/tags/builtin.md) — Provides `defaultTagHandlers()`, a `TagRegistry` populated with handlers for the most-used IANA-registered CBOR tags. C…
- [registry](./src/tags/registry.md) — `TagRegistry` is the in-memory mutable container for CBOR tag handlers. The decoder consults a snapshot of the registry…
- [tagged](./src/tags/tagged.md) — Provides the `Tagged<T>` value object used by `@suaveplan/cbor` to materialise RFC 8949 §3.4 tagged items. The decoder…
<!-- end:auto-docs --> - half-float — Decodes 2 big-endian bytes representin…
- [decoder](./src/decoder/decoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Decodes 2 big-endian bytes representin…
- [half-float](./src/decoder/half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
- [well-formed](./src/decoder/well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Encodes a JavaScript `number` as IEEE……
- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Encodes a JavaScript `number` as IEEE……
- [half-float](./src/encoder/half-float.md) — Encodes a JavaScript `number` as IEEE 754 binary16 (CBOR major 7 / value 25) when the round-trip is exact, and otherwis…
- [errors](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-decoder](./src/streaming/chunk-decoder.md) — Partial-item streaming decoder. While `PullDecoder` yields one whole CBOR item at a time (waiting until each item is fu…
- [pull-decoder](./src/streaming/pull-decoder.md) — `PullDecoder` is a pull-style streaming decoder over an `AsyncIterable<Uint8Array>` or `ReadableStream<Uint8Array>`. Ea…
- [builtin](./src/tags/builtin.md) — Provides `defaultTagHandlers()`, a `TagRegistry` populated with handlers for the most-used IANA-registered CBOR tags. C…
- [registry](./src/tags/registry.md) — `TagRegistry` is the in-memory mutable container for CBOR tag handlers. The decoder consults a snapshot of the registry…
- [tagged](./src/tags/tagged.md) — Provides the `Tagged<T>` value object used by `@suaveplan/cbor` to materialise RFC 8949 §3.4 tagged items. The decoder…
- half-float — Decodes 2 big-endian bytes representin…
- [decoder](./src/decoder/decoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Decodes 2 big-endian bytes representin…
- [half-float](./src/decoder/half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
- [well-formed](./src/decoder/well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Encodes a JavaScript `number` as IEEE……
- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Encodes a JavaScript `number` as IEEE……
- [half-float](./src/encoder/half-float.md) — Encodes a JavaScript `number` as IEEE 754 binary16 (CBOR major 7 / value 25) when the round-trip is exact, and otherwis…
- [errors](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-decoder](./src/streaming/chunk-decoder.md) — Partial-item streaming decoder. While `PullDecoder` yields one whole CBOR item at a time (waiting until each item is fu…
- [pull-decoder](./src/streaming/pull-decoder.md) — `PullDecoder` is a pull-style streaming decoder over an `AsyncIterable<Uint8Array>` or `ReadableStream<Uint8Array>`. Ea…
- [builtin](./src/tags/builtin.md) — Provides `defaultTagHandlers()`, a `TagRegistry` populated with handlers for the most-used IANA-registered CBOR tags. C…
- [registry](./src/tags/registry.md) — `TagRegistry` is the in-memory mutable container for CBOR tag handlers. The decoder consults a snapshot of the registry…
- [tagged](./src/tags/tagged.md) — Provides the `Tagged<T>` value object used by `@suaveplan/cbor` to materialise RFC 8949 §3.4 tagged items. The decoder…
- half-float — Decodes 2 big-endian bytes representin…
- [decoder](./src/decoder/decoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Decodes 2 big-endian bytes representin…
- [half-float](./src/decoder/half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
- [well-formed](./src/decoder/well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Encodes a JavaScript `number` as IEEE…
- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_- half-float — Encodes a JavaScript `number` as IEEE…
- [half-float](./src/encoder/half-float.md) — Encodes a JavaScript `number` as IEEE 754 binary16 (CBOR major 7 / value 25) when the round-trip is exact, and otherwis…
- [errors](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [error-codes](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-decoder](./src/streaming/chunk-decoder.md) — Partial-item streaming decoder. While `PullDecoder` yields one whole CBOR item at a time (waiting until each item is fu…
- [pull-decoder](./src/streaming/pull-decoder.md) — `PullDecoder` is a pull-style streaming decoder over an `AsyncIterable<Uint8Array>` or `ReadableStream<Uint8Array>`. Ea…
- [builtin](./src/tags/builtin.md) — Provides `defaultTagHandlers()`, a `TagRegistry` populated with handlers for the most-used IANA-registered CBOR tags. C…
- [registry](./src/tags/registry.md) — `TagRegistry` is the in-memory mutable container for CBOR tag handlers. The decoder consults a snapshot of the registry…
- [tagged](./src/tags/tagged.md) — Provides the `Tagged<T>` value object used by `@suaveplan/cbor` to materialise RFC 8949 §3.4 tagged items. The decoder…
- [decoder](./src/decoder/decoder.md) — <!-- begin:auto-docs --> _(no submodules)_- [half-float](./src/decoder/half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
- [well-formed](./src/decoder/well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
- [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_ - [deterministic](./src/deterministic/deterministic.md) — <!-- begin:auto-docs --> _(no submodules)_- [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_ - [diagnostic](./src/diagnostic/diagnostic.md) — <!-- begin:auto-docs --> _(no submodules)_- [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_ - [encoder](./src/encoder/encoder.md) — <!-- begin:auto-docs --> _(no submodules)_ - [half-float](./src/encoder/half-float.md) — Encodes a JavaScript `number` as IEEE 754 binary16 (CBOR major 7 / value 25) when the round-trip is exact, and otherwis…
- [errors](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_ - [error-codes](./src/errors/error-codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_ - [sequences](./src/sequences/sequences.md) — <!-- begin:auto-docs --> _(no submodules)_- [chunk-decoder](./src/streaming/chunk-decoder.md) — Partial-item streaming decoder. While `PullDecoder` yields one whole CBOR item at a time (waiting until each item is fu…
- [pull-decoder](./src/streaming/pull-decoder.md) — `PullDecoder` is a pull-style streaming decoder over an `AsyncIterable<Uint8Array>` or `ReadableStream<Uint8Array>`. Ea…
- [builtin](./src/tags/builtin.md) — Provides `defaultTagHandlers()`, a `TagRegistry` populated with handlers for the most-used IANA-registered CBOR tags. C…
- [registry](./src/tags/registry.md) — `TagRegistry` is the in-memory mutable container for CBOR tag handlers. The decoder consults a snapshot of the registry…
- [tagged](./src/tags/tagged.md) — Provides the `Tagged<T>` value object used by `@suaveplan/cbor` to materialise RFC 8949 §3.4 tagged items. The decoder…
## Install
```bash
bun add @suaveplan/cbor
```
## Quick Start
```ts
import { encode, decode } from "@suaveplan/cbor";
const bytes = encode({ a: 1, b: [true, "two"] });
const value = decode(bytes);
```
## Modules
| Module | Doc |
|---|---|
| `encoder` | [`src/encoder/encoder.md`](src/encoder/encoder.md) |
| `encoder/half-float` | [`src/encoder/half-float.md`](src/encoder/half-float.md) |
| `decoder` | [`src/decoder/decoder.md`](src/decoder/decoder.md) |
| `decoder/half-float` | [`src/decoder/half-float.md`](src/decoder/half-float.md) |
| `decoder/well-formed` | [`src/decoder/well-formed.md`](src/decoder/well-formed.md) |
| `streaming/pull-decoder` | [`src/streaming/pull-decoder.md`](src/streaming/pull-decoder.md) |
| `deterministic` | [`src/deterministic/deterministic.md`](src/deterministic/deterministic.md) |
| `diagnostic` | [`src/diagnostic/diagnostic.md`](src/diagnostic/diagnostic.md) |
| `cose/cose-key` | [`src/cose/cose-key.md`](src/cose/cose-key.md) |
| `cose/jwk` | [`src/cose/jwk.md`](src/cose/jwk.md) |
| `cose/alg-map` | [`src/cose/alg-map.md`](src/cose/alg-map.md) |
| `cose/headers` | [`src/cose/headers.md`](src/cose/headers.md) |
| `cose/sig-structure` | [`src/cose/sig-structure.md`](src/cose/sig-structure.md) |
| `cose/sign1` | [`src/cose/sign1.md`](src/cose/sign1.md) |
| `cose/mac0` | [`src/cose/mac0.md`](src/cose/mac0.md) |
| `cwt/claims` | [`src/cwt/claims.md`](src/cwt/claims.md) |
| `cwt/verify` | [`src/cwt/verify.md`](src/cwt/verify.md) |
| `streaming/chunk-decoder` | [`src/streaming/chunk-decoder.md`](src/streaming/chunk-decoder.md) |
| `cose/sign` | [`src/cose/sign.md`](src/cose/sign.md) |
| `cose/mac` | [`src/cose/mac.md`](src/cose/mac.md) |
| `cose/encrypt0` | [`src/cose/encrypt0.md`](src/cose/encrypt0.md) |
| `cose/encrypt` | [`src/cose/encrypt.md`](src/cose/encrypt.md) |
| `tags/registry` | [`src/tags/registry.md`](src/tags/registry.md) |
| `tags/tagged` | [`src/tags/tagged.md`](src/tags/tagged.md) |
| `tags/builtin` | [`src/tags/builtin.md`](src/tags/builtin.md) |
| `sequences` | [`src/sequences/sequences.md`](src/sequences/sequences.md) |
| `errors` | [`src/errors/error-codes.md`](src/errors/error-codes.md) |
## Subpath exports
- `@suaveplan/cbor` — root barrel: `encode`, `decode`, `Tagged`, error codes
- `@suaveplan/cbor/encoder` — encoder + half-float
- `@suaveplan/cbor/decoder` — decoder + half-float + `isWellFormed`
- `@suaveplan/cbor/streaming` — `PullDecoder` over async-iterable / WHATWG streams
- `@suaveplan/cbor/sequences` — RFC 8742
- `@suaveplan/cbor/deterministic` — `encodeDeterministic` shortcut for §4.2
- `@suaveplan/cbor/diagnostic` — RFC 8949 §8 notation emitter
- `@suaveplan/cbor/cose` — `COSE_Key` ↔ JWK + IANA algorithm bridge (RFC 9052 §7), Sig_structure builders (§4.4 / §6.3 / §5.3), `COSE_Sign1` encode/decode/verify (§4.2, ES256/EdDSA), `COSE_Mac0` create/encode/decode/verify (§6.2, HS256/384/512)
- `@suaveplan/cbor/cwt` — RFC 8392 CBOR Web Token claim encode/decode + `verifyCwtSign1` / `verifyCwtMac0` with time-window + audience + issuer validation
- `@suaveplan/cbor/cddl` — RFC 8610 CDDL lexer + parser + AST + validator (primitive prelude, ranges, choices, arrays, maps, occurrence indicators, `.size`/`.regexp`/`.cbor` control operators, generics, named references)
- `@suaveplan/cbor/tags` — `Tagged`, `TagRegistry`, `defaultTagHandlers`
- `@suaveplan/cbor/errors` — `CBOR_CODES`, `CborError`, `CborErrorCode`
## Conformance
- RFC 8949 §3.1 — major types 0–7 encode + decode
- RFC 8949 §3.2 — indefinite-length text/byte strings, arrays, maps (decoder)
- RFC 8949 §3.3 — IEEE 754 binary16 encode (opt-in) + decode (always-on)
- RFC 8949 §3.4 — tagged-item registry
- RFC 8949 §4.1 — preferred serialization (shortest-form integers always-on,
shortest-exact float widths)
- RFC 8949 §4.2 — deterministic-encoding profile (sorted map keys, no
indefinite-length, half-float disabled in deterministic mode)
- RFC 8949 §5.1 — strict-mode well-formedness; every malformed-input class
raises `CborError(MALFORMED)`
- RFC 8742 §2 + §3 — CBOR Sequences encode + decode + async-iterator stream