Native Avro fixtures (alpha)
avroAdapter(schema, options) prepares a bounded in-memory Avro schema using avsc@5.7.9. fromAvro provides the shared immutable builder. Nothing is loaded from schema names, file paths, or URLs. Runtime-loaded schemas return unknown, not an invented TypeScript application type.
import { fromAvro } from '@mimlet/avro';
const events = fromAvro({
type: 'record',
name: 'Event',
fields: [{ name: 'id', type: 'long' }],
});
const event = events.with({ id: 9007199254740993n }).buildValidated();The adapter exposes create, check, issues, clone, encode, decode, standard, session, identity, metadata, and builder. The profiles are minimal, defaults, random, and boundary. Generation uses explicit scoped sessions, never the native library's global random generator. Defaults are fresh per build, not shared mutable objects. Recursive unions select branches that can terminate within the depth budget; impossible required recursion fails clearly.
Representations and validation
Longs are signed 64-bit bigint values, with a native low-level long codec so no intermediate JavaScript number loses precision. Ints remain 32-bit numbers. Float inputs must already be representable as 32-bit floats (use Math.fround); nonfinite IEEE values remain supported. Bytes and fixed values accept Uint8Array or Buffer; cloned/decoded data uses independent Buffer instances. Records are returned as plain objects.
Unions always use explicit branch wrappers, except null. For example, ['int', 'long'] accepts { int: 1 } or { long: 1n }. Named union branches use fully qualified names. A record field is required even when the schema supplies a default. Validated builds do not insert fields, drop extras, or coerce input. Logical types retain their underlying wire representation and are identified as such in metadata; no Date/decimal conversion is invented. Executable logical-type hooks are deliberately not read from a schema document.
Binary and resource boundaries
encode and decode handle one raw Avro datum, not an object container file, a schema-registry framing protocol, or Avro RPC. Decode rejects trailing bytes. Before native decoding, a structural scan bounds collection expansion and recursion, validates UTF-8 and primitive sizes, and checks block lengths. This prevents a tiny array-of-null payload from allocating billions of values.
Schemas and inputs reject accessors, unexpected class instances, cycles, sparse arrays, and non-data properties before native processing. Schema node/depth/size, output node/depth/byte, and collection budgets are configurable. The pinned native decoder cannot safely retain the __proto__ map key; this key is rejected for both input and wire maps instead of silently losing it. Duplicate wire map keys and unsafe native schema names are also rejected explicitly.
These checks are not an OS sandbox. Native schema compilation still executes library-generated validation code. Use process isolation for hostile schemas or strict resource containment. Error paths do not print fixture values; an attached native cause can contain vendor diagnostics and should be treated accordingly.
The compatibility suite tests actual tarballs, native-encoder agreement, signed 64-bit boundaries, field defaults, unions, recursive fixtures, replay, isolated values, declaration types, and adversarial binary expansion before decoding.