Skip to content

aead-napi: replace reserved scalar wrapper keys with wrapper classes #382

Closed

Description

@coderdan

Problem

vitaminc-aead-napi maps calendar dates, sub-millisecond timestamps and decimals to one-key wrapper objects: { date }, { timestamp }, { decimal }. Those keys are reserved. An object with exactly one own enumerable property of that name is always read as a wrapper.

Go and Rust can store the same shape as ordinary data, so decrypting it in JS and encrypting it again is lossy:

  • {"date": "2024-01-01"} written by Go comes back as a date scalar.
  • {"date": "tomorrow"} throws ERR_INVALID_DATE on re-encryption.

#381 documents this limitation (raised in review: #381 (comment)).

Proposal

Represent these scalars as instances of small wrapper classes, for example VcDate, VcTimestamp and VcDecimal, exported by the Node package. The converter already rejects anything that isn't a plain object, so an instance can never collide with plain data from another language. Classes also type cleanly in TypeScript and can control JSON output through toJSON.

We considered and rejected Symbol.for(...) keys. They are collision-free, but JSON.stringify, structuredClone, postMessage and Object.keys all drop symbol keys, so decrypted values would silently become {} in common pipelines.

Open design points

  • How the addon registers the class constructors with the library, since vitaminc-aead-napi is a library and not the addon itself. One option is to have the converter take the constructor references.
  • How instances are recognised on input (a brand symbol on the prototype, or instanceof against the registered constructors).
  • How to migrate from the current wrapper objects: accept both for one release, or switch in a single breaking release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions