@uncefact/untp-utils
v0.4.0
Published
Shared utility primitives for UNTP packages and consumers.
Readme
@uncefact/untp-utils
Shared utility primitives for UNTP packages and consumers.
Installation
npm install @uncefact/untp-utilsSub-entries
The package root exports only StructuredError, the base class every
sub-entry throws from. Each capability is imported from its own subpath so a
consumer only pulls in the dependencies it needs.
| Subpath | Provides |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| @uncefact/untp-utils/multibase-digest | MultibaseDigest: encode, decode and verify multibase-encoded multihashes. |
| @uncefact/untp-utils/common | Document-field readers (asDateTime, asNonEmptyString, makeRequireString), evaluateValidityWindow and ValidityWindowOutcome, and canonicalJson for deterministic JSON serialisation. |
| @uncefact/untp-utils/artefacts | UNTP schema, context and docs URL helpers, the isV070OrAbove version predicate, and detectVersionFromContext. |
| @uncefact/untp-utils/conformity-vocabulary | Parses a UNTP conformity scheme or catalogue, including ConformityScore, ConformityScoringFramework and ConformityRequiredPerformance, and validates a conformity claim against it, covering score-code membership and ConformityReferenceResolution catalogue tier references. |
| @uncefact/untp-utils/validation | Validates a payload against JSON Schema and expands it as JSON-LD, both guarded against SSRF. |
| @uncefact/untp-utils/loaders | The schema and JSON-LD document loaders validation runs on. |
| @uncefact/untp-utils/resolvers | IP-pinned document fetching with a conditional-fetch skip chain. |
| @uncefact/untp-utils/node | validatePublicUrl, the SSRF guard the other sub-entries fetch through, with its isPrivateHostname, isPrivateIpv4 and isPrivateIpv6 predicates and its error classes. |
| @uncefact/untp-utils/cache | createInMemoryTtlCache, a bounded in-memory TTL cache. |
| @uncefact/untp-utils/bundled-artefacts | The bundled UNTP and VCDM schemas and contexts, keyed by published URL. |
| @uncefact/untp-utils/http-headers | HTTP header parsing, and the default User-Agent guarded fetches send. |
Every sub-entry throws a typed error class on failure rather than returning an outcome object. See RELEASE_NOTES.md for what each release changes and CHANGELOG.md for the full history.
MultibaseDigest
Encode, decode and verify multibase-encoded multihashes.
import { MultibaseDigest } from '@uncefact/untp-utils/multibase-digest';
// Hash some data, wrap as a multihash, encode as a multibase string.
const digest = await MultibaseDigest.fromData(new TextEncoder().encode('hello'), {
algorithm: 'sha2-256',
base: 'base58btc',
});
digest.toString(); // e.g. "zQmYwAPJzv5..." (base58btc)
digest.toString('base64'); // e.g. "mEiBL..." (re-encoded, no rehash)
// Parse a multibase string. Algorithm and encoding are read from the string.
const parsed = MultibaseDigest.fromString(digest.toString());
parsed.algorithm; // "sha2-256"
parsed.base; // "base58btc"
// Verify against original data.
await parsed.verify(new TextEncoder().encode('hello')); // true | falseSupported algorithms: sha2-256, sha2-512.
Supported multibase encodings: base58btc, base64.
Bundled UNTP artefacts
The bundle contains the enumerated artefacts for UNTP 0.6.0, 0.6.1 and 0.7.0: the five core credential schemas and their per-type contexts for 0.6.0 and 0.6.1, those five schemas plus the Conformity Scheme and Identity Resolver link set schemas and the unified context for 0.7.0, together with the W3C Verifiable Credentials Data Model v2 context and schema. These artefacts ship inside the package under artefacts/ and are listed in artefacts/manifest.json. createSchemaLoader and createJsonLdDocumentLoader serve the bundled copy when the host cannot deliver one of those URLs (its name does not resolve, it cannot be reached, it answers a non-2xx status, it returns a body that is not JSON, or it exceeds the resolver's size, redirect or time bounds), and the optional onBundledFallback callback runs only when a substitution happens, not on cache hits. Two failures are deliberately not covered and surface exactly as before: a URL the SSRF guard refused (url.private-address, url.private-hostname, url.unsupported-scheme or url.invalid anywhere on the cause chain), because a UNTP host resolving to a private address is a signal the operator must see, and any error that is not a typed resolver or resolution failure, because a bug in the fetch path must not read as an outage. The 0.6.x context entries are indexed under both the base URLs the schemas declare (.../dpp/0.6.1/) and their /context/ aliases (.../dpp/0.6.1/context/). isHostDeliveryFailure is the rule, exported for consumers that want the same split. Pass bundledFallback: false to switch the fallback off. URLs the bundle does not carry fail exactly as before.
Consumers can also read the bundle directly through @uncefact/untp-utils/bundled-artefacts, keyed by the published URL, for example to validate against a schema with no network at all:
import { findBundledArtefact, loadBundledArtefacts } from '@uncefact/untp-utils/bundled-artefacts';
const linksetSchema = await findBundledArtefact(
'https://untp.unece.org/artefacts/schema/v0.7.0/idr/LinksetSchema.json',
);
const everything = await loadBundledArtefacts(); // ReadonlyMap<url, artefact>The raw JSON files and artefacts/manifest.json (URL, file, source and sha256 per artefact) ship in the package too.
Published artefacts are immutable once released, so the bundle only grows when a new UNTP version is released. scripts/refresh-artefacts.mjs fetches every artefact from its source of truth (the specification repository at the release tag for 0.7.0 and later, the publishing host for earlier versions), writes any it does not have yet, refuses to overwrite a bundled copy that differs from the published one, and regenerates the src/bundle/ modules the loaders import.
pnpm --filter @uncefact/untp-utils artefacts:check # dry run: compare the bundle with what is published; fails on any difference
pnpm --filter @uncefact/untp-utils artefacts:refresh # add newly listed artefacts to the bundleTo add a version, add its entries to ARTEFACTS in the script and run artefacts:refresh. A bundled copy that differs from the published one is overwritten only with node scripts/refresh-artefacts.mjs --force, after the difference has been understood.
