Documentation
¶
Overview ¶
Package anyuri builds and parses any:// URIs — the canonical string convention for referencing anything inside any: an object, a dataset record, an identity (mention), a space, a property value, a file.
The typed grammar (docs/19-links.md is the semantics contract):
any://<kind>/<spaceId>[/<rest…>][?<params>][#<fragment>] any://o/<spaceId>/<objectId> object any://o/<spaceId>/<objectId>/<dataset>/<recordId> dataset record any://m/<spaceId>/<identity> identity (mention) any://s/<spaceId> space any://p/<spaceId>/<objectId>/<propId> property value any://f/<spaceId>/<fileId>[?variant=<tag>] file (files-v2)
plus the two legacy bare forms, which keep parsing as kind "o" (Legacy: true) and are never rewritten:
any://<objectId> in-space reference (the property-value form) any://<spaceId>/<objectId> global reference
Kind slugs are a reserved lexical namespace: a first path segment of 1-4 lowercase-alphanumeric bytes is always a kind slug, anything longer is a legacy bare id. Real ids are ≥40-char base58 strings, so no collision is possible; the one behavior delta vs the pre-typed parser is that a pathological ≤4-char object id no longer parses. Future kinds must keep their slugs within this shape.
The kind set is open. A well-formed URI with an unrecognized kind slug (including the reserved invite kind "i") parses to ErrKindUnknown — the caller's "degrade to a plain link" branch — which is distinct from ErrInvalid ("reject"). Unknown query params are ignored, never a failure. #fragment is a view-level anchor only and never identifies a data record.
Property values of link-format properties use the strict bare one-segment, fragment-less form; check IsPropertyValueRef.
Index ¶
- Constants
- Variables
- func BuildFile(spaceId, fileId string) string
- func BuildFileVariant(spaceId, fileId, variant string) string
- func BuildMention(spaceId, identity string) string
- func BuildObject(objectId string) string
- func BuildObjectGlobal(spaceId, objectId string) string
- func BuildProp(spaceId, objectId, propId string) string
- func BuildRecord(spaceId, objectId, dataset, recordId string) string
- func BuildSpace(spaceId string) string
- func ExtractMentions(text string) []string
- func IsPropertyValueRef(s string) bool
- func IsValid(s string) bool
- type Kind
- type URI
Constants ¶
const Scheme = "any"
Scheme is the URI scheme, without separators.
Variables ¶
var ErrInvalid = errors.New("anyuri: invalid any:// URI")
ErrInvalid is wrapped by every malformed-URI parse failure; classify with errors.Is. A consumer rejects these.
var ErrKindUnknown = errors.New("anyuri: unknown link kind")
ErrKindUnknown is returned for a well-formed typed URI whose kind slug this parser doesn't know (a future kind, or the reserved "i"). It does NOT wrap ErrInvalid: errors.Is(err, ErrKindUnknown) is the renderer's "degrade to a plain, non-magic link" branch — don't error, don't guess.
Functions ¶
func BuildFile ¶
BuildFile returns "any://f/<spaceId>/<fileId>". fileId is the payloads-row id (per-attach, space-unique), never rootCid.
func BuildFileVariant ¶
BuildFileVariant returns "any://f/<spaceId>/<fileId>?variant=<tag>".
func BuildMention ¶
BuildMention returns "any://m/<spaceId>/<identity>".
func BuildObject ¶
BuildObject returns the bare in-space reference "any://<objectId>" — the strict form relation property values require. New typed references should prefer BuildObjectGlobal.
func BuildObjectGlobal ¶
BuildObjectGlobal returns "any://o/<spaceId>/<objectId>".
func BuildProp ¶
BuildProp returns "any://p/<spaceId>/<objectId>/<propId>" — a property VALUE on an object, keyed by the content-addressed propId (never xKey).
func BuildRecord ¶
BuildRecord returns "any://o/<spaceId>/<objectId>/<dataset>/<recordId>" — a record inside an object's dataset (editor block, chat message).
func ExtractMentions ¶
ExtractMentions scans text for mention URIs (any://m/<spaceId>/<identity>) and returns the mentioned identities, deduplicated, in first-occurrence order. It is a substring scan, not a markdown parser: it works identically on raw text and on CommonMark link destinations ("[Zarko](any://m/<sp>/<id>)" — an unescaped ")" legally terminates a CommonMark destination, and ids are base58 so no terminator byte can appear inside one). Percent-encoded destinations are not decoded; ids never need encoding. This is the sanctioned mention scanner — the chat mentions derivation and any client-side detection share it. A filter over ExtractLinks, the general scanner.
func IsPropertyValueRef ¶
IsPropertyValueRef reports whether s is exactly the strict form relation property values require: the bare one-segment, fragment-less "any://<objectId>".
Types ¶
type Kind ¶
type Kind string
Kind is the first path segment of a typed URI — what the link points at. The set is open; unknown kinds parse to ErrKindUnknown.
type URI ¶
type URI struct {
Kind Kind
SpaceId string // every typed kind; empty only for the legacy in-space form
ObjectId string // o, p
Dataset string // o record path …/<dataset>/<recordId>
RecordId string // o record path
PropId string // p
Identity string // m
FileId string // f
Variant string // f: ?variant=<tag>
Fragment string // view-level anchor; never a data-record id
Legacy bool // parsed from a bare pre-typed form
}
URI is a parsed any:// reference. Kind is always set on success; which other fields are populated depends on it. Legacy marks the two pre-typed bare forms (kind "o"; SpaceId empty for the in-space property-value form). Known params become fields (Variant); unknown params are dropped on Parse and do not round-trip.
func ExtractLinks ¶
ExtractLinks scans text for any:// URIs of every known kind and returns them parsed, deduplicated by their text form, in first-occurrence order. Unknown kinds and malformed tokens are skipped. Like ExtractMentions it is a substring scan, not a markdown parser: it finds raw tokens and CommonMark link destinations alike (an unescaped ")" legally terminates a destination, and ids are base58, so no terminator byte can appear inside one). A glued sentence period after the last id segment is shed ("…/<id>.Next"). Percent-encoding is not decoded: '%' ends a token, so an encoded id truncates rather than resolving — ids never need encoding.
This is the sanctioned link scanner: the server's link index and clients detecting links in text share it.
func Parse ¶
Parse decodes any of the typed forms plus the two legacy bare forms. Malformed input wraps ErrInvalid; a well-formed URI of an unknown kind wraps ErrKindUnknown (see the package doc for the distinction).
func (URI) Canonical ¶
Canonical returns the index-key form of u: the typed global shape with the fragment and every param dropped, a legacy in-space reference resolved against spaceId. Returns false for a URI that is not a link target — a space reference, an unresolvable in-space form (no spaceId in hand), an empty id.
any://<id>, any://<sp>/<id>, any://o/<sp>/<id> → any://o/<sp>/<id> any://o/<sp>/<id>/<ds>/<rec> → unchanged any://p/<sp>/<id>/<prop> → unchanged any://m/<sp>/<identity> → unchanged any://f/<sp>/<file>[?variant=…] → any://f/<sp>/<file> any://s/<sp> → not a target
func (URI) IsPart ¶
IsPart reports whether a canonical target names a part of an object — a dataset record or a property value — rather than the object.
func (URI) ObjectKey ¶
ObjectKey returns the canonical object reference a target belongs to — "any://o/<sp>/<id>" for an object, one of its records or one of its property values — and false for targets that are not objects (identities, files). Callers key "who links this object, in any of its parts" on it.