Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120import { isCid, isDatetime, isDid, isNsid, isRecordKey, isTid, parseCanonicalResourceUri} from "@atcute/lexicons/syntax";import type { CanonicalResourceUri, Cid as RawCid, Datetime as RawDatetime, Did as RawDid, Nsid as RawNsid, RecordKey as RawRecordKey, ResourceUri as RawResourceUri, Tid as RawTid} from "@atcute/lexicons/syntax";export type { RawCid, RawDatetime, RawResourceUri };
// asserting wrappers over atcute's syntax guards for xrpc input boundaries.// untrusted strings (user input, route params, storage) get rejected here// instead of traveling to the server and failing as a 400.declare const tag: unique symbol;
type Lewitype<T, N extends string> = T & { readonly [tag]: N };
export type Did = Lewitype<RawDid, "Did">;export type Nsid = Lewitype<RawNsid, "Nsid">;export type Rkey = Lewitype<RawRecordKey, "Rkey">;export type Tid = Lewitype<RawTid, "Tid">;export type Cid = Lewitype<RawCid, "Cid">;export type AtUri = Lewitype<CanonicalResourceUri, "AtUri">;export type Datetime = Lewitype<RawDatetime, "Datetime">;export type KnotOrigin = Lewitype<string, "KnotOrigin">;export type GitOid = Lewitype<string, "GitOid">;export type LabelKey = Lewitype<string, "LabelKey">;export type Capability = Lewitype<string, "Capability">;export type ProxyPath = Lewitype<string, "ProxyPath">;
const invalid = (kind: string, value: string): Error => new Error(`"${value}" is not a valid ${kind}.`);
export const didOf = (value: string): Did => { if (!isDid(value)) throw invalid("DID", value); return value as Did;};
export const nsidOf = (value: string): Nsid => { if (!isNsid(value)) throw invalid("NSID", value); return value as Nsid;};
export const recordKeyOf = (value: string): Rkey => { if (!isRecordKey(value)) throw invalid("rkey", value); return value as Rkey;};
export const tidOf = (value: string): Tid => { if (!isTid(value)) throw invalid("TID", value); return value as Tid;};
export const cidOf = (value: string): Cid => { if (!isCid(value)) throw invalid("CID", value); return value as Cid;};
export const atUriOf = (value: string): AtUri => { parseCanonicalResourceUri(value); return value as AtUri;};
export const datetimeOf = (value: string): Datetime => { if (!isDatetime(value)) throw invalid("datetime", value); return value as Datetime;};
export const knotOf = (value: string): KnotOrigin => { const parsed = URL.parse(`https://${value}`); if (parsed === null || parsed.host !== value || parsed.pathname !== "/") throw invalid("knot origin", value); return value as KnotOrigin;};
const GIT_OID = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
export const gitOidOf = (value: string): GitOid => { if (!GIT_OID.test(value)) throw invalid("git OID", value); return value as GitOid;};
const LABEL_KEY = /^(?!did:)[A-Za-z0-9._~-]{1,512}$/;
export const labelKeyOf = (value: string): LabelKey => { if (!LABEL_KEY.test(value)) throw invalid("label key", value); return value as LabelKey;};
const CAPABILITY = /^\S+$/;
export const capabilityOf = (value: string): Capability => { if (value.length === 0 || value.length > 512 || !CAPABILITY.test(value)) throw invalid("cap", value); return value as Capability;};
const PROXY_PATH = /^_[A-Za-z0-9.-]+$/;
export const proxyPathOf = (value: string): ProxyPath => { if (!PROXY_PATH.test(value)) throw invalid("proxy path", value); return value as ProxyPath;};
export type XrpcPath = Nsid | ProxyPath;
export const xrpcPathOf = (value: string): XrpcPath => value.startsWith("_") ? proxyPathOf(value) : nsidOf(value);