168 lines
4.3 KiB
TypeScript
168 lines
4.3 KiB
TypeScript
import type { Ghost } from './classes.ghost.js';
|
|
import * as plugins from './ghost.plugins.js';
|
|
|
|
export interface IAuthor {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
profile_image?: string;
|
|
cover_image?: string;
|
|
bio?: string;
|
|
website?: string;
|
|
location?: string;
|
|
facebook?: string;
|
|
twitter?: string;
|
|
meta_title?: string;
|
|
meta_description?: string;
|
|
url: string;
|
|
}
|
|
|
|
export interface ITag {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
description?: string;
|
|
feature_image?: string;
|
|
visibility: string;
|
|
og_image?: string;
|
|
og_title?: string;
|
|
og_description?: string;
|
|
twitter_image?: string;
|
|
twitter_title?: string;
|
|
twitter_description?: string;
|
|
meta_title?: string;
|
|
meta_description?: string;
|
|
codeinjection_head?: string;
|
|
codeinjection_foot?: string;
|
|
canonical_url?: string;
|
|
accent_color?: string;
|
|
url: string;
|
|
}
|
|
|
|
export interface IPost {
|
|
id: string;
|
|
uuid: string;
|
|
title: string;
|
|
slug: string;
|
|
html: string;
|
|
comment_id: string;
|
|
feature_image?: string;
|
|
featured: boolean;
|
|
visibility: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
published_at: string;
|
|
custom_excerpt?: string;
|
|
codeinjection_head?: string | null;
|
|
codeinjection_foot?: string | null;
|
|
custom_template?: string | null;
|
|
canonical_url?: string | null;
|
|
url: string;
|
|
excerpt?: string;
|
|
reading_time: number;
|
|
access: boolean;
|
|
comments: boolean;
|
|
og_image?: string | null;
|
|
og_title?: string | null;
|
|
og_description?: string | null;
|
|
twitter_image?: string | null;
|
|
twitter_title?: string | null;
|
|
twitter_description?: string | null;
|
|
meta_title?: string | null;
|
|
meta_description?: string | null;
|
|
email_subject?: string | null;
|
|
frontmatter?: string | null;
|
|
feature_image_alt?: string | null;
|
|
feature_image_caption?: string | null;
|
|
authors: IAuthor[];
|
|
tags: ITag[];
|
|
primary_author: IAuthor;
|
|
primary_tag: ITag;
|
|
[key: string]: any; // To allow for additional properties
|
|
}
|
|
|
|
export class Post {
|
|
public ghostInstanceRef: Ghost;
|
|
public postData: IPost;
|
|
|
|
constructor(ghostInstanceRefArg: Ghost, postData: IPost) {
|
|
this.ghostInstanceRef = ghostInstanceRefArg;
|
|
this.postData = postData;
|
|
}
|
|
|
|
public getId(): string {
|
|
return this.postData.id;
|
|
}
|
|
|
|
public getTitle(): string {
|
|
return this.postData.title;
|
|
}
|
|
|
|
public getHtml(): string {
|
|
return this.postData.html;
|
|
}
|
|
|
|
public getExcerpt(): string {
|
|
return this.postData.excerpt || this.generateExcerpt();
|
|
}
|
|
|
|
public getFeatureImage(): string | undefined {
|
|
return this.postData.feature_image;
|
|
}
|
|
|
|
public getAuthor(): IAuthor {
|
|
return this.postData.primary_author;
|
|
}
|
|
|
|
public toJson(): IPost {
|
|
return this.postData;
|
|
}
|
|
|
|
public async update(postData: Partial<IPost>): Promise<Post> {
|
|
try {
|
|
// Only send fields that should be updated, not the entire post object with nested relations
|
|
const updatePayload: any = {
|
|
id: this.postData.id,
|
|
updated_at: this.postData.updated_at, // Required for conflict detection
|
|
...postData
|
|
};
|
|
|
|
// Remove read-only or computed fields that shouldn't be sent
|
|
delete updatePayload.uuid;
|
|
delete updatePayload.comment_id;
|
|
delete updatePayload.url;
|
|
delete updatePayload.excerpt;
|
|
delete updatePayload.reading_time;
|
|
delete updatePayload.created_at; // Don't send created_at in updates
|
|
delete updatePayload.primary_author;
|
|
delete updatePayload.primary_tag;
|
|
delete updatePayload.count;
|
|
delete updatePayload.email;
|
|
delete updatePayload.newsletter;
|
|
|
|
// Remove nested objects if they're not being updated
|
|
if (!postData.authors) delete updatePayload.authors;
|
|
if (!postData.tags) delete updatePayload.tags;
|
|
if (!postData.tiers) delete updatePayload.tiers;
|
|
|
|
const updatedPostData = await this.ghostInstanceRef.adminApi.posts.edit(updatePayload);
|
|
this.postData = updatedPostData;
|
|
return this;
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
public async delete(): Promise<void> {
|
|
try {
|
|
await this.ghostInstanceRef.adminApi.posts.delete({ id: this.getId() });
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
private generateExcerpt(length: number = 100): string {
|
|
const plainText = this.postData.html.replace(/<[^>]+>/g, ''); // Strip HTML tags
|
|
return plainText.length > length ? plainText.substring(0, length) + '...' : plainText;
|
|
}
|
|
} |