first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
# `@suaveplan/license` — codec/payload
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`packPayload` and `unpackPayload` are the 72-bit payload codec on top of
the bitpack primitives. They emit exactly 9 bytes (the binary contract
shared with upstream `@suaveplan/license`) and walk the 9 schema fields
in the canonical order declared by `FIELD_BITS`.
`packPayload` raises `LicenseError(LICENSE.PAYLOAD_OUT_OF_RANGE)` when a
field exceeds its declared bit width (via the underlying bitpacker).
`unpackPayload` raises `LicenseError(LICENSE.MALFORMED)` for any input
length other than `PAYLOAD_BYTES` (9).
## Features
- Bit-for-bit wire compatibility with upstream's `packPayload` /
`unpackPayload`.
- Field-bound validation via `SimpleBitPacker.packUint`, surfaced as
typed `LicenseError`s.
- Strict 9-byte length invariant on both sides — no implicit truncation
or padding.
- Returns a fresh `Uint8Array`; safe to mutate the caller's buffer.
## Usage: Basic
```ts
import {
packPayload,
unpackPayload,
} from "@suaveplan/license/codec/payload/payload";
import { PackageTier, TimeEncodingType } from "@suaveplan/license/types/license";
const bytes = packPayload({
version: 2,
signingKeyId: 0,
productId: 1,
packageTier: PackageTier.PRO,
flags: 0,
timeEncodingType: TimeEncodingType.NONE,
timeValue: 0,
featureMask: 0,
nonce: 0x123,
});
console.log(bytes.length); // 9
const round = unpackPayload(bytes);
```
## Usage: Advanced
Catching a field-overflow at the generation boundary:
```ts
import { LicenseError } from "@suaveplan/license";
import { packPayload } from "@suaveplan/license/codec/payload/payload";
try {
packPayload({ /* ...valid */ productId: 64 } as never); // 6 bits, max 63
} catch (err) {
if (err instanceof LicenseError && err.code === "LICENSE.PAYLOAD_OUT_OF_RANGE") {
// surface to the user as a form-validation failure
}
}
```
## API Reference
### `packPayload(payload: LicensePayload): Uint8Array`
Pack a payload to its 9-byte representation. Throws
`LicenseError(LICENSE.PAYLOAD_OUT_OF_RANGE)` on field overflow.
### `unpackPayload(data: Uint8Array): LicensePayload`
Unpack a 9-byte buffer. Throws `LicenseError(LICENSE.MALFORMED)` for
any other length.
## Implementation Notes
The unpacker casts `timeEncodingType` to the `TimeEncodingType` enum
even though the bit width (2) admits any value in `[0, 3]` — all four
values map to legitimate enum members, so the cast is safe. The
constant `PAYLOAD_BYTES = 9` lives in `constants/constants.ts` so any
future schema change (which would require a `LICENSE_VERSION` bump)
updates a single source of truth.