Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110"use server";import { TID } from "@atproto/common";import { AtpBaseClient, PubLeafletPublication } from "lexicons/api";import { createOauthClient } from "src/atproto-oauth";import { getIdentityData } from "actions/getIdentityData";import { supabaseServerClient } from "supabase/serverClient";import { Un$Typed } from "@atproto/api";import { Json } from "supabase/database.types";import { Vercel } from "@vercel/sdk";import { isProductionDomain } from "src/utils/isProductionDeployment";import { string } from "zod";
const VERCEL_TOKEN = process.env.VERCEL_TOKEN;const vercel = new Vercel({ bearerToken: VERCEL_TOKEN,});let subdomainValidator = string() .min(3) .max(63) .regex(/^[a-z0-9-]+$/);export async function createPublication({ name, description, iconFile, subdomain, preferences,}: { name: string; description: string; iconFile: File | null; subdomain: string; preferences: Omit<PubLeafletPublication.Preferences, "$type">;}) { let isSubdomainValid = subdomainValidator.safeParse(subdomain); if (!isSubdomainValid.success) { return { success: false }; } const oauthClient = await createOauthClient(); let identity = await getIdentityData(); if (!identity || !identity.atp_did) return;
let domain = `${subdomain}.leaflet.pub`;
let credentialSession = await oauthClient.restore(identity.atp_did); let agent = new AtpBaseClient( credentialSession.fetchHandler.bind(credentialSession), ); let record: Un$Typed<PubLeafletPublication.Record> = { name, base_path: domain, preferences, };
if (description) { record.description = description; }
// Upload the icon if provided if (iconFile && iconFile.size > 0) { const buffer = await iconFile.arrayBuffer(); const uploadResult = await agent.com.atproto.repo.uploadBlob( new Uint8Array(buffer), { encoding: iconFile.type }, );
if (uploadResult.data.blob) { record.icon = uploadResult.data.blob; } }
let result = await agent.pub.leaflet.publication.create( { repo: credentialSession.did!, rkey: TID.nextStr(), validate: false }, record, );
//optimistically write to our db! let { data: publication } = await supabaseServerClient .from("publications") .upsert({ uri: result.uri, identity_did: credentialSession.did!, name: record.name, record: { ...record, $type: "pub.leaflet.publication", } as unknown as Json, }) .select() .single();
// Create the custom domain if (isProductionDomain()) { await vercel.projects.addProjectDomain({ idOrName: "prj_9jX4tmYCISnm176frFxk07fF74kG", teamId: "team_42xaJiZMTw9Sr7i0DcLTae9d", requestBody: { name: domain, }, }); } await supabaseServerClient .from("custom_domains") .insert({ domain, confirmed: true, identity: null }); await supabaseServerClient .from("publication_domains") .insert({ domain, publication: result.uri, identity: identity.atp_did });
return { success: true, publication };}