feat(classes.ghost): Add members, settings and webhooks support; implement Member class and add tests

This commit is contained in:
2025-10-07 14:29:36 +00:00
parent cf10f51089
commit 76c2b714b5
15 changed files with 1173 additions and 4 deletions

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@apiclient.xyz/ghost',
version: '1.3.0',
version: '1.4.0',
description: 'An unofficial Ghost CMS API package enabling content and admin functionality for managing posts.'
}

View File

@@ -3,6 +3,7 @@ import { Post, type IPost, type ITag, type IAuthor } from './classes.post.js';
import { Author } from './classes.author.js';
import { Tag } from './classes.tag.js';
import { Page, type IPage } from './classes.page.js';
import { Member, type IMember } from './classes.member.js';
export interface IGhostConstructorOptions {
baseUrl: string;
@@ -72,7 +73,7 @@ export class Ghost {
public async getPostById(id: string): Promise<Post> {
try {
const postData = await this.contentApi.posts.read({ id });
return new Post(postData, this.adminApi);
return new Post(this, postData);
} catch (error) {
console.error(`Error fetching post with id ${id}:`, error);
throw error;
@@ -82,7 +83,7 @@ export class Ghost {
public async createPost(postData: IPost): Promise<Post> {
try {
const createdPostData = await this.adminApi.posts.add(postData);
return new Post(createdPostData, this.adminApi);
return new Post(this, createdPostData);
} catch (error) {
console.error('Error creating post:', error);
throw error;
@@ -305,4 +306,123 @@ export class Ghost {
throw error;
}
}
public async getMembers(optionsArg?: { filter?: string; limit?: number }): Promise<Member[]> {
try {
const limit = optionsArg?.limit || 1000;
const membersData = await this.adminApi.members.browse({ limit });
if (optionsArg?.filter) {
const matcher = new plugins.smartmatch.SmartMatch(optionsArg.filter);
return membersData
.filter((member: IMember) => matcher.match(member.email))
.map((member: IMember) => new Member(this, member));
}
return membersData.map((member: IMember) => new Member(this, member));
} catch (error) {
console.error('Error fetching members:', error);
throw error;
}
}
public async getMemberById(id: string): Promise<Member> {
try {
const memberData = await this.adminApi.members.read({ id });
return new Member(this, memberData);
} catch (error) {
console.error(`Error fetching member with id ${id}:`, error);
throw error;
}
}
public async getMemberByEmail(email: string): Promise<Member> {
try {
const memberData = await this.adminApi.members.read({ email });
return new Member(this, memberData);
} catch (error) {
console.error(`Error fetching member with email ${email}:`, error);
throw error;
}
}
public async createMember(memberData: Partial<IMember>): Promise<Member> {
try {
const createdMemberData = await this.adminApi.members.add(memberData);
return new Member(this, createdMemberData);
} catch (error) {
console.error('Error creating member:', error);
throw error;
}
}
public async getSettings(): Promise<any> {
try {
return await this.adminApi.settings.browse();
} catch (error) {
console.error('Error fetching settings:', error);
throw error;
}
}
public async updateSettings(settings: any[]): Promise<any> {
try {
return await this.adminApi.settings.edit(settings);
} catch (error) {
console.error('Error updating settings:', error);
throw error;
}
}
public async getWebhooks(): Promise<any[]> {
try {
return await this.adminApi.webhooks.browse();
} catch (error) {
console.error('Error fetching webhooks:', error);
throw error;
}
}
public async getWebhookById(id: string): Promise<any> {
try {
return await this.adminApi.webhooks.read({ id });
} catch (error) {
console.error(`Error fetching webhook with id ${id}:`, error);
throw error;
}
}
public async createWebhook(webhookData: {
event: string;
target_url: string;
name?: string;
secret?: string;
api_version?: string;
integration_id?: string;
}): Promise<any> {
try {
return await this.adminApi.webhooks.add(webhookData);
} catch (error) {
console.error('Error creating webhook:', error);
throw error;
}
}
public async updateWebhook(id: string, webhookData: any): Promise<any> {
try {
return await this.adminApi.webhooks.edit({ ...webhookData, id });
} catch (error) {
console.error('Error updating webhook:', error);
throw error;
}
}
public async deleteWebhook(id: string): Promise<void> {
try {
await this.adminApi.webhooks.delete({ id });
} catch (error) {
console.error(`Error deleting webhook with id ${id}:`, error);
throw error;
}
}
}

87
ts/classes.member.ts Normal file
View File

@@ -0,0 +1,87 @@
import type { Ghost } from './classes.ghost.js';
export interface IMember {
id: string;
uuid: string;
email: string;
name?: string;
note?: string;
geolocation?: string;
enable_comment_notifications?: boolean;
subscribed?: boolean;
email_count?: number;
email_opened_count?: number;
email_open_rate?: number;
status?: string;
created_at: string;
updated_at: string;
labels?: Array<{
id: string;
name: string;
slug: string;
}>;
subscriptions?: any[];
avatar_image?: string;
comped?: boolean;
email_suppression?: {
suppressed: boolean;
info?: string;
};
}
export class Member {
public ghostInstanceRef: Ghost;
public memberData: IMember;
constructor(ghostInstanceRefArg: Ghost, memberData: IMember) {
this.ghostInstanceRef = ghostInstanceRefArg;
this.memberData = memberData;
}
public getId(): string {
return this.memberData.id;
}
public getEmail(): string {
return this.memberData.email;
}
public getName(): string | undefined {
return this.memberData.name;
}
public getStatus(): string | undefined {
return this.memberData.status;
}
public getLabels(): Array<{ id: string; name: string; slug: string }> | undefined {
return this.memberData.labels;
}
public toJson(): IMember {
return this.memberData;
}
public async update(memberData: Partial<IMember>): Promise<Member> {
try {
const updatedMemberData = await this.ghostInstanceRef.adminApi.members.edit({
...memberData,
id: this.getId()
});
this.memberData = updatedMemberData;
return this;
} catch (error) {
console.error('Error updating member:', error);
throw error;
}
}
public async delete(): Promise<void> {
try {
await this.ghostInstanceRef.adminApi.members.delete({ id: this.getId() });
} catch (error) {
console.error(`Error deleting member with id ${this.getId()}:`, error);
throw error;
}
}
}

View File

@@ -2,4 +2,5 @@ export * from './classes.ghost.js';
export * from './classes.post.js';
export * from './classes.author.js';
export * from './classes.tag.js';
export * from './classes.page.js';
export * from './classes.page.js';
export * from './classes.member.js';