A CLI for publishing standard.site documents to ATProto sequoia.pub
standard site lexicon cli publishing

feat: add option to disable publishing (text) content

authored by willow.sh and committed by tangled.org 594cd435 da42a8c8

+40 -10
+6
packages/cli/src/commands/init.ts
··· 98 98 message: "URL path prefix for posts:", 99 99 placeholder: "/posts, /blog, /articles, etc.", 100 100 }), 101 + publishContent: () => 102 + confirm({ 103 + message: "Publish the post content on the standard.site document?", 104 + initialValue: true, 105 + }), 101 106 }, 102 107 { onCancel }, 103 108 ); ··· 341 346 pdsUrl, 342 347 frontmatter: frontmatterMapping, 343 348 bluesky: blueskyConfig, 349 + publishContent: siteConfig.publishContent, 344 350 }); 345 351 346 352 const configPath = path.join(process.cwd(), "sequoia.json");
+9
packages/cli/src/commands/update.ts
··· 162 162 stripDatePrefix: configUpdated.stripDatePrefix, 163 163 pathTemplate: configUpdated.pathTemplate, 164 164 textContentField: configUpdated.textContentField, 165 + publishContent: configUpdated.publishContent, 165 166 bluesky: configUpdated.bluesky, 166 167 }); 167 168 ··· 373 374 }), 374 375 ); 375 376 377 + const publishContent = exitOnCancel( 378 + await confirm({ 379 + message: "Publish the post content on the standard.site document?", 380 + initialValue: config.publishContent ?? true, 381 + }), 382 + ); 383 + 376 384 const textContentField = exitOnCancel( 377 385 await text({ 378 386 message: ··· 397 405 removeIndexFromSlug: removeIndexFromSlug || undefined, 398 406 stripDatePrefix: stripDatePrefix || undefined, 399 407 textContentField: textContentField || undefined, 408 + publishContent: publishContent ?? true, 400 409 }; 401 410 } 402 411
+11 -9
packages/cli/src/lib/atproto.ts
··· 252 252 ); 253 253 const publishDate = new Date(post.frontmatter.publishDate); 254 254 255 - // Determine textContent: use configured field from frontmatter, or fallback to markdown body 256 - let textContent: string; 255 + // Determine textContent (if enabled): use configured field from frontmatter, or fallback to markdown body 256 + let textContent: string | null = null; 257 257 if ( 258 + config.publishContent && 258 259 config.textContentField && 259 260 post.rawFrontmatter?.[config.textContentField] 260 261 ) { 261 262 textContent = String(post.rawFrontmatter[config.textContentField]); 262 - } else { 263 + } else if (config.publishContent) { 263 264 textContent = stripMarkdownForText(post.content); 264 265 } 265 266 ··· 268 269 title: post.frontmatter.title, 269 270 site: config.publicationUri, 270 271 path: postPath, 271 - textContent: textContent.slice(0, 10000), 272 + textContent: textContent?.slice(0, 10000), 272 273 publishedAt: publishDate.toISOString(), 273 274 canonicalUrl: `${config.siteUrl}${postPath}`, 274 275 }; ··· 317 318 ); 318 319 const publishDate = new Date(post.frontmatter.publishDate); 319 320 320 - // Determine textContent: use configured field from frontmatter, or fallback to markdown body 321 - let textContent: string; 321 + // Determine textContent (if enabled): use configured field from frontmatter, or fallback to markdown body 322 + let textContent: string | null = null; 322 323 if ( 324 + config.publishContent && 323 325 config.textContentField && 324 326 post.rawFrontmatter?.[config.textContentField] 325 327 ) { 326 328 textContent = String(post.rawFrontmatter[config.textContentField]); 327 - } else { 329 + } else if (config.publishContent) { 328 330 textContent = stripMarkdownForText(post.content); 329 331 } 330 332 ··· 342 344 title: post.frontmatter.title, 343 345 site: config.publicationUri, 344 346 path: postPath, 345 - textContent: textContent.slice(0, 10000), 347 + textContent: textContent?.slice(0, 10000), 346 348 publishedAt: publishDate.toISOString(), 347 349 canonicalUrl: `${config.siteUrl}${postPath}`, 348 350 }; ··· 384 386 title: string; 385 387 site: string; 386 388 path: string; 387 - textContent: string; 389 + textContent?: string; 388 390 publishedAt: string; 389 391 canonicalUrl?: string; 390 392 description?: string;
+8 -1
packages/cli/src/lib/config.ts
··· 85 85 stripDatePrefix?: boolean; 86 86 pathTemplate?: string; 87 87 textContentField?: string; 88 + publishContent?: boolean; 88 89 bluesky?: BlueskyConfig; 89 90 }): string { 90 91 const config: Record<string, unknown> = { 91 - $schema: 'https://tangled.org/stevedylan.dev/sequoia/raw/main/sequoia.schema.json', 92 + $schema: 93 + "https://tangled.org/stevedylan.dev/sequoia/raw/main/sequoia.schema.json", 92 94 siteUrl: options.siteUrl, 93 95 contentDir: options.contentDir, 94 96 }; ··· 138 140 if (options.textContentField) { 139 141 config.textContentField = options.textContentField; 140 142 } 143 + 144 + if (options.publishContent) { 145 + config.publishContent = options.publishContent; 146 + } 147 + 141 148 if (options.bluesky) { 142 149 config.bluesky = options.bluesky; 143 150 }
+1
packages/cli/src/lib/types.ts
··· 41 41 stripDatePrefix?: boolean; // Remove YYYY-MM-DD- prefix from filenames (Jekyll-style, default: false) 42 42 pathTemplate?: string; // URL path template with tokens like {year}/{month}/{day}/{slug} (overrides pathPrefix + slug) 43 43 textContentField?: string; // Frontmatter field to use for textContent instead of markdown body 44 + publishContent?: boolean; // Whether or not to publish the documents content on the standard.site document (default: true) 44 45 bluesky?: BlueskyConfig; // Optional Bluesky posting configuration 45 46 ui?: UIConfig; // Optional UI components configuration 46 47 }
+5
sequoia.schema.json
··· 116 116 "type": "string", 117 117 "description": "Frontmatter field to use for textContent instead of markdown body" 118 118 }, 119 + "publishContent": { 120 + "type": "boolean", 121 + "description": "Whether or not to publish the documents content on the standard.site document", 122 + "default": true 123 + }, 119 124 "bluesky": { 120 125 "type": "object", 121 126 "additionalProperties": false,