import { AccountRole, type InviteSecret, cojsonInternals } from "cojson"; import { Account } from "../coValues/account.js"; import type { CoValue, CoValueClassOrSchema } from "../internal.js"; /** * @category Invite Links * @deprecated Use the options object form: `createInviteLink(value, role, { baseURL, valueHint? })` */ export function createInviteLink( value: C, role: AccountRole, baseURL: string, valueHint?: string, ): string; /** @category Invite Links */ export function createInviteLink( value: C, role: AccountRole, options: { baseURL: string; valueHint?: string }, ): string; export function createInviteLink( value: C, role: AccountRole, baseURLOrOptions: string | { baseURL: string; valueHint?: string }, valueHint?: string, ): string { const baseURL = typeof baseURLOrOptions === "string" ? baseURLOrOptions : baseURLOrOptions.baseURL; const hint = typeof baseURLOrOptions === "string" ? valueHint : baseURLOrOptions.valueHint; const coValueCore = value.$jazz.raw.core; let currentCoValue = coValueCore; while (currentCoValue.verified.header.ruleset.type === "ownedByGroup") { currentCoValue = currentCoValue.getGroup().core; } const { ruleset, meta } = currentCoValue.verified.header; if (ruleset.type !== "group" || meta?.type === "account") { throw new Error("Can't create invite link for object without group"); } const group = cojsonInternals.expectGroup(currentCoValue.getCurrentContent()); const inviteSecret = group.createInvite(role); return `${baseURL}#/invite/${hint ? hint + "/" : ""}${ value.$jazz.id }/${inviteSecret}`; } /** @category Invite Links */ export function parseInviteLink(inviteURL: string): | { valueID: string; valueHint?: string; inviteSecret: InviteSecret; } | undefined { const url = new URL(inviteURL); const parts = url.hash.split("/"); let valueHint: string | undefined; let valueID: string | undefined; let inviteSecret: InviteSecret | undefined; if (parts[0] === "#" && parts[1] === "invite") { if (parts.length === 5) { valueHint = parts[2]; valueID = parts[3]; inviteSecret = parts[4] as InviteSecret; } else if (parts.length === 4) { valueID = parts[2]; inviteSecret = parts[3] as InviteSecret; } if (!valueID || !inviteSecret) { return undefined; } return { valueID, inviteSecret, valueHint }; } } /** @category Invite Links */ export function consumeInviteLink({ inviteURL, as = Account.getMe(), forValueHint, invitedObjectSchema, }: { inviteURL: string; as?: Account; forValueHint?: string; invitedObjectSchema: S; }): Promise< | { valueID: string; valueHint?: string; inviteSecret: InviteSecret; } | undefined > { return new Promise((resolve, reject) => { const result = parseInviteLink(inviteURL); if (result && result.valueHint === forValueHint) { as.acceptInvite(result.valueID, result.inviteSecret, invitedObjectSchema) .then(() => { resolve(result); }) .catch(reject); } else { resolve(undefined); } }); }