Expand description
JSON-LD term expansion for ActivityPub documents, over bundled contexts.
ActivityPub is JSON-LD, which means a key is not a name but an abbreviation
for an IRI, and the @context says which. Two servers can describe the same
thing with different keys — sensitive, as:sensitive, or any term aliased
to either — and a reader that matches on spelling reads one and drops the
other. This crate resolves keys to the IRIs they stand for, and puts them
back into ojak’s own spelling.
use ojak_jsonld::{Registry, normalize};
use serde_json::json;
let registry = Registry::bundled();
let document = json!({
"@context": ["https://www.w3.org/ns/activitystreams", {"s": "as:sensitive"}],
"type": "Note",
"id": "https://remote.example/notes/1",
"s": true
});
let normalized = normalize(®istry, &document).expect("normalize");
// The alias is gone; the term ojak reads is there.
assert_eq!(normalized.document()["sensitive"], json!(true));§What this is not
It is not a general JSON-LD processor, and does not try to be. It resolves
only the contexts in contexts/, because resolution happens on inbound
attacker-controlled documents and a loader that fetches what they name is a
request-forgery primitive; see contexts/README.md. A context it does not
ship is read as ActivityStreams, which every context the fediverse serves
extends, so its standard terms mean what they always do and only the
sender’s own additions go unread; Processed::unresolved_contexts says
which contexts those were. It rejects @graph,
@included and @reverse outright, for reasons recorded on
Error::RestructuringKeyword. It has no flattening, no framing, and no
@nest, @index maps, @id maps or @type maps — none of which appear
in ActivityPub traffic.
It does turn a document into RDF and canonicalise it (rdf), because
that is what a Linked Data Signature signs; see that module for how it is
stricter than the reading path. A caller checking such a signature over a
context it fetched, as Mastodon does, adds the fetched document to a
registry (Registry::with); the fetching itself, and its rules, are the
caller’s.
What it does cover is the JSON-LD 1.1 needed by the contexts the fediverse
actually serves: term and compact-IRI expansion, @vocab, @base,
@language and language maps, @container sets and lists, type coercion,
and property- and type-scoped contexts. The last of those is not optional:
security/data-integrity/v1 hangs proofValue and cryptosuite off a
scoped context on DataIntegrityProof, and those are the fields ojak
verifies integrity proofs with.
One simplification is worth knowing about when reading compacted output.
JSON-LD compaction may split a single property across two terms, writing an
untagged value under content and language-tagged ones under contentMap.
Ojak picks one term for a property and writes every value under it. The
result is valid JSON-LD carrying every value, and re-expands to the same
thing, but it is not always the term a given server would have chosen.
Modules§
- rdf
- RDF, and its canonical form: what a Linked Data Signature signs.
Structs§
- Limits
- Ceilings on the work one document may cause.
- NoCache
- A
ContextCachethat keeps nothing: every context is processed afresh. - Processed
- A processed document, and what could not be resolved while processing it.
- Processed
Context - A
@contextvalue already processed, kept to be used again. - Registry
- The contexts available to a processing run.
Enums§
- Error
- Why a document could not be processed.
Traits§
- Context
Cache - Where processed contexts are kept between documents.
Functions§
- compact
- Compact an expanded document against
context. - compact_
with compact, with limits of the caller’s choosing.- expand
- Expand a document: every key becomes the IRI it stands for.
- expand_
with expand, with limits of the caller’s choosing.- normalize
- Read a document however it was written, and hand it back in ojak’s own spelling.
- normalize_
with normalize, with limits of the caller’s choosing.- normalize_
with_ cache normalize_with, keeping processed contexts incache.- ojak_
context - The
@contextvalue ojak emits and compacts to.