feat: add updated at support 772647ab
Willow (GHOST) · 2026-03-10 07:01 4 file(s) · +46 −1
packages/cli/src/lib/atproto.ts +22 −1
26 26
		typeof v.site === "string" &&
27 27
		typeof v.path === "string" &&
28 28
		typeof v.textContent === "string" &&
29 -
		typeof v.publishedAt === "string"
29 +
		typeof v.publishedAt === "string" &&
30 +
		(v.updatedAt === undefined || typeof v.updatedAt === "string")
30 31
	);
31 32
}
32 33
252 253
	);
253 254
	const publishDate = new Date(post.frontmatter.publishDate);
254 255
256 +
	// Handle updatedAt: only set if explicitly provided in frontmatter
257 +
	let updatedAt: Date | undefined;
258 +
	if (post.frontmatter.updatedAt) {
259 +
		updatedAt = new Date(post.frontmatter.updatedAt);
260 +
	}
261 +
255 262
	// Determine textContent (if enabled): use configured field from frontmatter, or fallback to markdown body
256 263
	let textContent: string | null = null;
257 264
	if (
273 280
		publishedAt: publishDate.toISOString(),
274 281
		canonicalUrl: `${config.siteUrl}${postPath}`,
275 282
	};
283 +
284 +
	if (updatedAt) {
285 +
		record.updatedAt = updatedAt.toISOString();
286 +
	}
276 287
277 288
	if (post.frontmatter.description) {
278 289
		record.description = post.frontmatter.description;
318 329
	);
319 330
	const publishDate = new Date(post.frontmatter.publishDate);
320 331
332 +
	// Handle updatedAt: only set if explicitly provided in frontmatter
333 +
	let updatedAt = post.frontmatter.updatedAt
334 +
		? new Date(post.frontmatter.updatedAt)
335 +
		: undefined;
336 +
321 337
	// Determine textContent (if enabled): use configured field from frontmatter, or fallback to markdown body
322 338
	let textContent: string | null = null;
323 339
	if (
348 364
		publishedAt: publishDate.toISOString(),
349 365
		canonicalUrl: `${config.siteUrl}${postPath}`,
350 366
	};
367 +
368 +
	if (updatedAt) {
369 +
		record.updatedAt = updatedAt.toISOString();
370 +
	}
351 371
352 372
	if (post.frontmatter.description) {
353 373
		record.description = post.frontmatter.description;
388 408
	path: string;
389 409
	textContent?: string;
390 410
	publishedAt: string;
411 +
	updatedAt?: string;
391 412
	canonicalUrl?: string;
392 413
	description?: string;
393 414
	coverImage?: BlobObject;
packages/cli/src/lib/markdown.ts +17 −0
75 75
		}
76 76
	}
77 77
78 +
	// Updated date mapping - check custom field first, then fallbacks
79 +
	const updatedAtField = mapping?.updatedAt;
80 +
	if (updatedAtField && raw[updatedAtField]) {
81 +
		frontmatter.updatedAt = raw[updatedAtField];
82 +
	} else if (raw.updatedAt) {
83 +
		frontmatter.updatedAt = raw.updatedAt;
84 +
	} else {
85 +
		// Fallback to common date field names
86 +
		const updatedAtFields = ["updated_at", "modifiedAt", "modified_at"];
87 +
		for (const field of updatedAtFields) {
88 +
			if (raw[field]) {
89 +
				frontmatter.updatedAt = raw[field];
90 +
				break;
91 +
			}
92 +
		}
93 +
	}
94 +
78 95
	// Cover image mapping
79 96
	const coverField = mapping?.coverImage || "ogImage";
80 97
	frontmatter.ogImage = raw[coverField] || raw.ogImage;
packages/cli/src/lib/types.ts +2 −0
2 2
	title?: string; // Field name for title (default: "title")
3 3
	description?: string; // Field name for description (default: "description")
4 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")
5 6
	coverImage?: string; // Field name for cover image (default: "ogImage")
6 7
	tags?: string; // Field name for tags (default: "tags")
7 8
	draft?: string; // Field name for draft status (default: "draft")
90 91
	description?: string;
91 92
	bskyPost?: string;
92 93
	publishDate: string;
94 +
	updatedAt?: string;
93 95
	tags?: string[];
94 96
	ogImage?: string;
95 97
	atUri?: string;
sequoia.schema.json +5 −0
70 70
					"description": "Field name for publish date (checks \"publishDate\", \"pubDate\", \"date\", \"createdAt\", and \"created_at\" by default)",
71 71
					"default": "publishDate"
72 72
				},
73 +
				"updatedAt": {
74 +
					"type": "string",
75 +
					"description": "Field name for updated date (checks \"updatedAt\", \"updated_at\", \"modifiedAt\", and \"modified_at\" by default)",
76 +
					"default": "updatedAt"
77 +
				},
73 78
				"coverImage": {
74 79
					"type": "string",
75 80
					"description": "Field name for cover image",