| 1 | export interface FrontmatterMapping { |
| 2 | title?: string; // Field name for title (default: "title") |
| 3 | description?: string; // Field name for description (default: "description") |
| 4 | publishDate?: string; // Field name for publish date (default: "publishDate", also checks "pubDate", "date", "createdAt", "created_at") |
| 5 | updatedAt?: string; // Field name for updated date (default: "updatedAt", also checks "updated_at", "modifiedAt", "modified_at") |
| 6 | coverImage?: string; // Field name for cover image (default: "ogImage") |
| 7 | tags?: string; // Field name for tags (default: "tags") |
| 8 | draft?: string; // Field name for draft status (default: "draft") |
| 9 | slugField?: string; // Frontmatter field to use for slug (if set, uses frontmatter value; otherwise uses filepath) |
| 10 | } |
| 11 | |
| 12 | // Strong reference for Bluesky post (com.atproto.repo.strongRef) |
| 13 | export interface StrongRef { |
| 14 | uri: string; // at:// URI format |
| 15 | cid: string; // Content ID |
| 16 | } |
| 17 | |
| 18 | // Bluesky posting configuration |
| 19 | export interface BlueskyConfig { |
| 20 | enabled: boolean; |
| 21 | maxAgeDays?: number; // Only post if published within N days (default: 7) |
| 22 | } |
| 23 | |
| 24 | // UI components configuration |
| 25 | export interface UIConfig { |
| 26 | components: string; // Directory to install UI components (default: src/components) |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * Publisher configuration. |
| 31 | * |
| 32 | * Any field with a documented default must be kept in sync with |
| 33 | * `DEFAULT_PUBLISHER_CONFIG` in `config.ts`, and vice versa. |
| 34 | */ |
| 35 | export interface PublisherConfig { |
| 36 | siteUrl: string; |
| 37 | contentDir: string; |
| 38 | imagesDir?: string; // Directory containing cover images |
| 39 | publicDir?: string; // Static/public folder for .well-known files (default: public) |
| 40 | outputDir?: string; // Built output directory for inject command |
| 41 | pathPrefix?: string; // URL path prefix for posts (default: /posts) |
| 42 | publicationUri: string; |
| 43 | pdsUrl?: string; |
| 44 | identity?: string; // Which stored identity to use (matches identifier) |
| 45 | frontmatter?: FrontmatterMapping; // Custom frontmatter field mappings |
| 46 | ignore?: string[]; // Glob patterns for files to ignore (e.g., ["_index.md", "**/drafts/**"]) |
| 47 | removeIndexFromSlug?: boolean; // Remove "/index" or "/_index" suffix from paths (default: false) |
| 48 | stripDatePrefix?: boolean; // Remove YYYY-MM-DD- prefix from filenames (Jekyll-style, default: false) |
| 49 | pathTemplate?: string; // URL path template with tokens like {year}/{month}/{day}/{slug} (overrides pathPrefix + slug) |
| 50 | textContentField?: string; // Frontmatter field to use for textContent instead of markdown body |
| 51 | publishContent?: boolean; // Whether or not to publish the documents content on the standard.site document (default: true) |
| 52 | bluesky?: BlueskyConfig; // Optional Bluesky posting configuration |
| 53 | ui?: UIConfig; // Optional UI components configuration |
| 54 | autoSync?: boolean; // Automatically sync state from PDS before publishing (default: true) |
| 55 | } |
| 56 | |
| 57 | // Legacy credentials format (for backward compatibility during migration) |
| 58 | export interface LegacyCredentials { |
| 59 | pdsUrl: string; |
| 60 | identifier: string; |
| 61 | password: string; |
| 62 | } |
| 63 | |
| 64 | // App password credentials (explicit type) |
| 65 | export interface AppPasswordCredentials { |
| 66 | type: "app-password"; |
| 67 | pdsUrl: string; |
| 68 | identifier: string; |
| 69 | password: string; |
| 70 | } |
| 71 | |
| 72 | // OAuth credentials (references stored OAuth session) |
| 73 | // Note: pdsUrl is not needed for OAuth - the OAuth client resolves PDS from the DID |
| 74 | export interface OAuthCredentials { |
| 75 | type: "oauth"; |
| 76 | did: string; |
| 77 | handle: string; |
| 78 | } |
| 79 | |
| 80 | // Union type for all credential types |
| 81 | export type Credentials = AppPasswordCredentials | OAuthCredentials; |
| 82 | |
| 83 | // Helper to check credential type |
| 84 | export function isOAuthCredentials( |
| 85 | creds: Credentials, |
| 86 | ): creds is OAuthCredentials { |
| 87 | return creds.type === "oauth"; |
| 88 | } |
| 89 | |
| 90 | export function isAppPasswordCredentials( |
| 91 | creds: Credentials, |
| 92 | ): creds is AppPasswordCredentials { |
| 93 | return creds.type === "app-password"; |
| 94 | } |
| 95 | |
| 96 | export interface PostFrontmatter { |
| 97 | title: string; |
| 98 | description?: string; |
| 99 | bskyPost?: string; |
| 100 | publishDate: string; |
| 101 | updatedAt?: string; |
| 102 | tags?: string[]; |
| 103 | ogImage?: string; |
| 104 | atUri?: string; |
| 105 | draft?: boolean; |
| 106 | } |
| 107 | |
| 108 | export interface BlogPost { |
| 109 | filePath: string; |
| 110 | slug: string; |
| 111 | frontmatter: PostFrontmatter; |
| 112 | content: string; |
| 113 | rawContent: string; |
| 114 | rawFrontmatter: Record<string, unknown>; // For accessing custom fields like textContentField |
| 115 | coverImagePath?: string; |
| 116 | } |
| 117 | |
| 118 | export interface BlobRef { |
| 119 | $link: string; |
| 120 | } |
| 121 | |
| 122 | export interface BlobObject { |
| 123 | $type: "blob"; |
| 124 | ref: BlobRef; |
| 125 | mimeType: string; |
| 126 | size: number; |
| 127 | } |
| 128 | |
| 129 | export interface PublicationState extends StrongRef {} |
| 130 | |
| 131 | export interface PublisherState { |
| 132 | publication?: PublicationState; |
| 133 | posts: Record<string, PostState>; |
| 134 | } |
| 135 | |
| 136 | export interface PostState { |
| 137 | contentHash: string; |
| 138 | atUri?: string; |
| 139 | lastPublished?: string; |
| 140 | slug?: string; // The generated slug for this post (used by inject command) |
| 141 | bskyPostRef?: StrongRef; // Reference to corresponding Bluesky post |
| 142 | } |
| 143 | |
| 144 | export interface PublicationRecord { |
| 145 | $type: "site.standard.publication"; |
| 146 | url: string; |
| 147 | name: string; |
| 148 | description?: string; |
| 149 | icon?: BlobObject; |
| 150 | createdAt: string; |
| 151 | preferences?: { |
| 152 | showInDiscover?: boolean; |
| 153 | }; |
| 154 | } |