Something went wrong. Try again.
leaflet fork for copy edit / bug fixes forked from leaflet.pub/leaflet
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110import { cookies } from "next/headers";import { isUuid } from "./utils/isUuid";import type { Profile } from "./identity";import { deriveConnectedAccountStatus } from "stripe/accountStatus";import { supabaseServerClient } from "supabase/serverClient";
// Shared plumbing for the three identity fetchers (getIdentityData,// getViewerIdentity, getAuthIdentity). Deliberately not a "use server" module:// exporting an async fn from one would publish it as a client-callable// endpoint.
// A cookie value that isn't a uuid can't match any email_auth_tokens row, so// treating it as absent skips a guaranteed-empty query.export async function getValidAuthToken() { let cookieStore = await cookies(); let auth_token = cookieStore.get("auth_token")?.value || cookieStore.get("external_auth_token")?.value; if (!auth_token || !isUuid(auth_token)) return null; return auth_token;}
export async function getSessionDid() { let auth_token = await getValidAuthToken(); if (!auth_token) return null; let { data } = await supabaseServerClient .from("email_auth_tokens") .select("identities(atp_did)") .eq("id", auth_token) .eq("confirmed", true) .single(); return data?.identities?.atp_did ?? null;}
// Embed fragments shared by getIdentityData and getViewerIdentity's// `identities(...)` selects. getIdentityData sandwiches dashboard-only embeds// between the two groups, so they can't be joined into one fragment.export const SUBSCRIPTION_STATE_EMBEDS = `notifications(count), publication_subscriptions(*), publication_email_subscribers(publication, state), publication_memberships(publication, tier, status, current_period_end, cancel_at_period_end)`;
export const ENTITLEMENT_EMBEDS = `user_subscriptions(plan, status, current_period_end), stripe_connected_accounts(stripe_account_id, charges_enabled, payouts_enabled, details_submitted, requirements), user_entitlements(entitlement_key, granted_at, expires_at, source, metadata)`;
export type EntitlementRow = { entitlement_key: string; granted_at: string; expires_at: string | null; source: string | null; metadata: unknown;};
export type Entitlements = Record< string, { granted_at: string; expires_at: string | null; source: string | null; metadata: unknown; }>;
// Keys the embedded entitlement rows by entitlement_key, dropping expired ones.export function keyEntitlements( rows: EntitlementRow[] | null | undefined,): Entitlements { const now = new Date().toISOString(); const entitlements: Entitlements = {}; for (const row of rows || []) { if (row.expires_at && row.expires_at < now) continue; entitlements[row.entitlement_key] = { granted_at: row.granted_at, expires_at: row.expires_at, source: row.source, metadata: row.metadata, }; } return entitlements;}
// Derives the user-facing account status server-side and drops the raw Stripe// requirements JSON so it never ships in the identity payload.export function processConnectedAccount< T extends { charges_enabled: boolean; requirements: unknown },>(row: T | null | undefined) { if (!row) return null; const { requirements, ...rest } = row; return { ...rest, status: deriveConnectedAccountStatus(row) };}
// Reshape a cached profile into the legacy `bsky_profiles` row shape that// consumers (SubscribeButton, PubPreview, PostPreview, …) read off the// identity, so swapping the table join for the cache stays transparent.export function bskyProfileFromCache(profile: Profile | null) { if (!profile) return null; return { did: profile.did, handle: profile.handle, record: { did: profile.did, handle: profile.handle, displayName: profile.displayName ?? undefined, avatar: profile.avatar ?? undefined, description: profile.description ?? undefined, }, };}