anyuri

package
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 3 Imported by: 0

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

View Source
const Scheme = "any"

Scheme is the URI scheme, without separators.

Variables

View Source
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.

View Source
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

func BuildFile(spaceId, fileId string) string

BuildFile returns "any://f/<spaceId>/<fileId>". fileId is the payloads-row id (per-attach, space-unique), never rootCid.

func BuildFileVariant

func BuildFileVariant(spaceId, fileId, variant string) string

BuildFileVariant returns "any://f/<spaceId>/<fileId>?variant=<tag>".

func BuildMention

func BuildMention(spaceId, identity string) string

BuildMention returns "any://m/<spaceId>/<identity>".

func BuildObject

func BuildObject(objectId string) string

BuildObject returns the bare in-space reference "any://<objectId>" — the strict form relation property values require. New typed references should prefer BuildObjectGlobal.

func BuildObjectGlobal

func BuildObjectGlobal(spaceId, objectId string) string

BuildObjectGlobal returns "any://o/<spaceId>/<objectId>".

func BuildProp

func BuildProp(spaceId, objectId, propId string) string

BuildProp returns "any://p/<spaceId>/<objectId>/<propId>" — a property VALUE on an object, keyed by the content-addressed propId (never xKey).

func BuildRecord

func BuildRecord(spaceId, objectId, dataset, recordId string) string

BuildRecord returns "any://o/<spaceId>/<objectId>/<dataset>/<recordId>" — a record inside an object's dataset (editor block, chat message).

func BuildSpace

func BuildSpace(spaceId string) string

BuildSpace returns "any://s/<spaceId>".

func ExtractMentions

func ExtractMentions(text string) []string

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

func IsPropertyValueRef(s string) bool

IsPropertyValueRef reports whether s is exactly the strict form relation property values require: the bare one-segment, fragment-less "any://<objectId>".

func IsValid

func IsValid(s string) bool

IsValid reports whether s parses as a known any:// URI (unknown kinds are not valid — but distinguish them via Parse when degrading instead of rejecting).

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.

const (
	KindObject  Kind = "o" // object, or a record via /<dataset>/<recordId>
	KindMention Kind = "m" // identity / member (a mention)
	KindSpace   Kind = "s" // a space
	KindProp    Kind = "p" // a property value on an object
	KindFile    Kind = "f" // a file (files-v2 attach), variant via ?variant=

)

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(text string) []URI

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

func Parse(s string) (URI, error)

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

func (u URI) Canonical(spaceId string) (URI, bool)

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

func (u URI) IsPart() bool

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

func (u URI) ObjectKey() (string, bool)

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.

func (URI) String

func (u URI) String() string

String renders the URI back to its text form. Legacy URIs re-render in their bare form (stored values are never rewritten).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL