A CLI for publishing standard.site documents to ATProto

publish to litenote too

+78
+75
packages/cli/src/commands/publish-lite.ts
··· 1 + import { Agent } from "@atproto/api" 2 + import { BlogPost } from "../lib/types" 3 + 4 + const LEXICON = "space.litenote.note" 5 + const MAX_CONTENT = 10000 6 + 7 + export async function createNote( 8 + agent: Agent, 9 + post: BlogPost, 10 + atUri: string, 11 + ): Promise<void> { 12 + // Parse the atUri to get the site.standard.document rkey 13 + // Format: at://did:plc:xxx/collection/rkey 14 + const uriMatch = atUri.match(/^at:\/\/([^/]+)\/([^/]+)\/(.+)$/); 15 + if (!uriMatch) { 16 + throw new Error(`Invalid atUri format: ${atUri}`); 17 + } 18 + 19 + const [, , , rkey] = uriMatch; 20 + const publishDate = new Date(post.frontmatter.publishDate).toISOString(); 21 + 22 + const record: Record<string, unknown> = { 23 + $type: LEXICON, 24 + title: post.frontmatter.title, 25 + content: post.content.slice(0, MAX_CONTENT), 26 + createdAt: publishDate, 27 + publishedAt: publishDate, 28 + }; 29 + 30 + 31 + const response = await agent.com.atproto.repo.createRecord({ 32 + repo: agent.did!, 33 + collection: LEXICON, 34 + record, 35 + rkey, 36 + validate: false 37 + }); 38 + 39 + console.log("\n\n create -", response); 40 + } 41 + 42 + export async function updateNote( 43 + agent: Agent, 44 + post: BlogPost, 45 + atUri: string, 46 + ): Promise<void> { 47 + // Parse the atUri to get the rkey 48 + // Format: at://did:plc:xxx/collection/rkey 49 + const uriMatch = atUri.match(/^at:\/\/([^/]+)\/([^/]+)\/(.+)$/); 50 + if (!uriMatch) { 51 + throw new Error(`Invalid atUri format: ${atUri}`); 52 + } 53 + 54 + const [, , , rkey] = uriMatch; 55 + 56 + const publishDate = new Date(post.frontmatter.publishDate).toISOString(); 57 + 58 + const record: Record<string, unknown> = { 59 + $type: LEXICON, 60 + title: post.frontmatter.title, 61 + content: post.content.slice(0, MAX_CONTENT), 62 + createdAt: publishDate, 63 + publishedAt: publishDate, 64 + }; 65 + 66 + const response = await agent.com.atproto.repo.putRecord({ 67 + repo: agent.did!, 68 + collection: LEXICON, 69 + rkey: rkey!, 70 + record, 71 + validate: false 72 + }); 73 + 74 + console.log("\n\n update -", response); 75 + }
+3
packages/cli/src/commands/publish.ts
··· 26 26 } from "../lib/markdown"; 27 27 import type { BlogPost, BlobObject, StrongRef } from "../lib/types"; 28 28 import { exitOnCancel } from "../lib/prompts"; 29 + import { createNote, updateNote } from "./publish-lite" 29 30 30 31 export const publishCommand = command({ 31 32 name: "publish", ··· 316 317 317 318 if (action === "create") { 318 319 atUri = await createDocument(agent, post, config, coverImage); 320 + await createNote(agent, post, atUri) 319 321 s.stop(`Created: ${atUri}`); 320 322 321 323 // Update frontmatter with atUri ··· 332 334 } else { 333 335 atUri = post.frontmatter.atUri!; 334 336 await updateDocument(agent, post, atUri, config, coverImage); 337 + await updateNote(agent, post, atUri) 335 338 s.stop(`Updated: ${atUri}`); 336 339 337 340 // For updates, rawContent already has atUri