11---
22title : Node SDK
3- description : JavaScript and TypeScript bounded parsing, schema admission, multi-diagnostics, native ACL generation, canonical digests, and builders in @a3s-lab/acl.
3+ description : JavaScript and TypeScript bounded parsing, schema admission, multi-diagnostics, native generation, schema-aware canonical digests, and builders in @a3s-lab/acl.
44---
55
66# Node SDK
@@ -52,6 +52,7 @@ const generated = generate(new DocumentBuilder().block(provider).build());
5252| ` Schema ` , ` AttributeSchema ` , ` BlockSchema ` , ` ValueSchema ` | TypeScript definitions for closed-by-default document, block, and recursive value rules. |
5353| ` generate(doc) ` | Generate native ACL text with labels in block headers. |
5454| ` canonicalBytes(doc) ` , ` canonicalDigest(doc) ` | Produce stable cross-SDK bytes and an algorithm-prefixed SHA-256 digest. |
55+ | ` canonicalBytesWithSchema(doc, schema) ` , ` canonicalDigestWithSchema(doc, schema) ` | Recursively normalize schema-declared unordered block occurrences before producing bytes or a digest. |
5556| ` CanonicalError ` | Report non-finite numbers, non-scalar strings, and non-portable identifiers without echoing values. |
5657| ` string ` , ` number ` , ` boolean ` , ` bool ` , ` nullValue ` , ` list ` , ` call ` | Value constructors. |
5758| ` BlockBuilder ` , ` DocumentBuilder ` | Structured document builders. |
@@ -124,7 +125,8 @@ Schemas reject undeclared attributes, blocks, and object fields by default.
124125They can declare required or optional attributes, block occurrence and label
125126cardinalities, and recursive ` Any ` , ` String ` , ` Number ` , ` Bool ` , ` Null ` , ` List ` ,
126127` Object ` , ` Call ` , and ` OneOf ` rules. Extension points require the corresponding
127- explicit allow flag.
128+ explicit allow flag. A block rule's ` unordered: true ` metadata affects only
129+ schema-aware canonicalization, not validation.
128130
129131Schema reports use stable ` acl.schema.* ` codes and logical paths such as
130132` $.blocks.provider[0].attributes.api_key ` . Messages and paths never include
@@ -147,6 +149,44 @@ Use `canonicalBytes` or `canonicalDigest` for signatures, durable identity, and
147149cross-SDK comparisons. Canonical bytes preserve ordered ACL constructs while
148150sorting semantically unordered attribute and object keys.
149151
152+ After schema admission, use the schema-aware APIs when a trusted schema
153+ declares repeatable block occurrences as unordered:
154+
155+ ``` typescript
156+ import {
157+ canonicalBytes ,
158+ canonicalBytesWithSchema ,
159+ canonicalDigestWithSchema ,
160+ parse ,
161+ validateDocument ,
162+ type Schema ,
163+ } from ' @a3s-lab/acl' ;
164+
165+ const document = parse (' provider "z" {}\n provider "a" {}' );
166+ const schema: Schema = {
167+ blocks: {
168+ provider: {
169+ labels: {min: 1 , max: 1 },
170+ unordered: true ,
171+ },
172+ },
173+ };
174+ const report = validateDocument (document , schema );
175+ if (report .diagnostics .length > 0 || report .truncated ) {
176+ throw new Error (' document failed schema admission' );
177+ }
178+
179+ const orderedBytes = canonicalBytes (document );
180+ const normalizedBytes = canonicalBytesWithSchema (document , schema );
181+ const digest = canonicalDigestWithSchema (document , schema );
182+ ```
183+
184+ For each body, normalization recursively sorts occurrences of each same
185+ declared block name by canonical UTF-8 bytes while retaining their existing
186+ positions. Other block types, unknown blocks, labels, lists, calls, and
187+ unmarked blocks remain ordered. The schema-aware APIs use the schema only as
188+ normalization metadata and do not perform admission themselves.
189+
150190## Boundary
151191
152192The SDK parses, generates, builds, and validates declarative ACL document
0 commit comments