packages/cli/src/lib/types.ts 4.9 K raw
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
}