js/wasm api
Complete API reference for the @gnufoo/canaad npm package (0.5.1). Built from canaad-wasm via wasm-pack, with a hand-maintained JS wrapper layer.
versioning:
@gnufoo/canaad(npm) and the rust crates are versioned independently — npm at 0.5.x, rust at 0.3.x.
npm install @gnufoo/canaad@^0.5Main export — @gnufoo/canaad
The default entry point re-exports the WASM bindings directly.
canonicalize(json: string): Uint8Array
Parses and canonicalizes a JSON string to deterministic bytes per RFC 8785.
import { canonicalize } from '@gnufoo/canaad';
const bytes = canonicalize('{"v":1,"tenant":"acme","resource":"/doc/123","purpose":"encrypt"}');Throws JsError on invalid JSON or AAD constraint violation.
canonicalizeString(json: string): string
Same as canonicalize, but returns the canonical form as a UTF-8 string.
import { canonicalizeString } from '@gnufoo/canaad';
const str = canonicalizeString('{"v":1,"tenant":"acme","resource":"/doc/123","purpose":"encrypt"}');validate(json: string): boolean
Validates a JSON string against the AAD specification. Returns true or false — no error detail. Use canonicalize() or AadBuilder.build() when you need to distinguish the failure reason.
import { validate } from '@gnufoo/canaad';
if (!validate(untrustedInput)) { /* reject */ }hash(json: string): Uint8Array
SHA-256 hash of the canonical JSON form.
import { hash } from '@gnufoo/canaad';
const digest = hash('{"v":1,"tenant":"acme","resource":"/doc/123","purpose":"encrypt"}');Constants
| Name | Type | Value | Description |
|---|---|---|---|
SPEC_VERSION |
number |
1 |
Current AAD spec version |
MAX_SAFE_INTEGER |
number |
9007199254740991 |
2⁵³ − 1; ceiling for timestamp and integer extensions |
MAX_SERIALIZED_BYTES |
number |
16384 |
16 KiB cap on serialized AAD output |
AadBuilder
Fluent builder for constructing AAD objects. Chain setters, then call build() or buildString().
import { AadBuilder } from '@gnufoo/canaad';Constructor
new AadBuilder() — creates an empty builder.
Setters
All setters return this for chaining.
| Method | Argument | Constraint |
|---|---|---|
.tenant(value) |
string |
1–256 UTF-8 bytes, no NUL |
.resource(value) |
string |
1–1024 UTF-8 bytes, no NUL |
.purpose(value) |
string |
1+ UTF-8 bytes, no NUL |
.timestamp(ts) |
number |
Non-negative integer ≤ MAX_SAFE_INTEGER |
.extensionString(key, value) |
string, string |
Key format: x_<app>_<field> |
.extensionInt(key, value) |
string, number |
Key format: x_<app>_<field>; value: non-negative integer ≤ MAX_SAFE_INTEGER |
Validation is deferred. Setters store raw values. Constraints (NaN, Infinity, negative, fractional, above MAX_SAFE_INTEGER, field length limits) are checked when
build()orbuildString()is called.
Terminal methods
| Method | Returns | Description |
|---|---|---|
.build() |
Uint8Array |
Validates all fields, produces canonical AAD bytes |
.buildString() |
string |
Validates all fields, produces canonical AAD as UTF-8 string |
Both throw JsError on validation failure. Required fields: tenant, resource, purpose.
Subpath exports
@gnufoo/canaad/init
Manual WASM initialization. Call initWasm() once before using any WASM function.
import { initWasm, isInitialized } from '@gnufoo/canaad/init';| Function | Signature | Description |
|---|---|---|
initWasm |
(wasmModule?: WebAssembly.Module) => Promise<void> |
Initialize WASM. Pass a precompiled module in Workers; omit in browser. Safe to call multiple times — subsequent calls are no-ops. |
isInitialized |
() => boolean |
Returns true after initWasm() has completed. |
@gnufoo/canaad/meta
Package metadata and Zod schemas for structured tool integration.
import { meta, inputSchema, outputSchema } from '@gnufoo/canaad/meta';meta object:
| Field | Value |
|---|---|
id |
"canaad" |
name |
"canaad" |
description |
"canonicalize JSON for AAD (Additional Authenticated Data) per RFC 8785" |
category |
"crypto" |
executionType |
"hybrid" |
inputSchema — Zod discriminated union on action. Four actions:
canonicalize—{ action, input, outputFormat?: 'bytes' | 'string' }validate—{ action, input }hash—{ action, input, outputFormat?: 'hex' | 'base64' }build—{ action, tenant, resource, purpose, timestamp?, extensions?, outputFormat?: 'bytes' | 'string' }
outputSchema — Zod discriminated union matching each action's response shape.
@gnufoo/canaad/tool
Complete tool integration: merges metadata, WASM lifecycle, and an action dispatcher.
import { toolDefinition } from '@gnufoo/canaad/tool';toolDefinition exposes:
- All fields from
meta initWasm()andisInitialized()from initexecute(rawInput)— validates input againstinputSchema, dispatches to the matching WASM function, returns a typed result matchingoutputSchema
await toolDefinition.initWasm();
const result = await toolDefinition.execute({
action: 'build',
tenant: 'acme',
resource: '/doc/123',
purpose: 'encrypt',
outputFormat: 'string',
});
// { action: 'build', output: '{...}', outputFormat: 'string' }
execute()throwsWasmNotInitializedErrorif called beforeinitWasm()completes.
Errors
WasmNotInitializedError
Imported from @gnufoo/canaad/errors (also re-exported from @gnufoo/canaad/tool).
import { WasmNotInitializedError } from '@gnufoo/canaad/errors';| Property | Type | Value |
|---|---|---|
.name |
string |
"WasmNotInitializedError" |
.kind |
string |
"WasmNotInitializedError" — discriminant for branded error handling |
.message |
string |
"WASM not initialized. Call initWasm() first." |
try {
canonicalize(json);
} catch (e) {
if (e instanceof WasmNotInitializedError) {
await initWasm();
// retry
}
}