From b3f08fb64c6794a3b60de048b79a648fc1e9bb01 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Wed, 8 Oct 2025 09:14:45 +0000 Subject: [PATCH] BREAKING CHANGE(classes.ghost): Remove Settings and Webhooks browse/read APIs, remove noisy console.error logs, and update tests/docs --- changelog.md | 9 ++++ readme.md | 33 +------------- test/test.settings.node.ts | 62 -------------------------- test/test.webhook.node.ts | 91 ++++++-------------------------------- ts/00_commitinfo_data.ts | 2 +- ts/classes.author.ts | 1 - ts/classes.ghost.ts | 62 -------------------------- ts/classes.member.ts | 2 - ts/classes.page.ts | 2 - ts/classes.post.ts | 2 - ts/classes.tag.ts | 2 - 11 files changed, 24 insertions(+), 244 deletions(-) delete mode 100644 test/test.settings.node.ts diff --git a/changelog.md b/changelog.md index 1c2d17b..7e4953a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,14 @@ # Changelog +## 2025-10-08 - 2.0.0 - BREAKING CHANGE(classes.ghost) +Remove Settings and Webhooks browse/read APIs, remove noisy console.error logs, and update tests/docs + +- Removed Settings API methods from Ghost: getSettings and updateSettings (breaking change). +- Removed Webhooks browsing/reading methods from Ghost: getWebhooks and getWebhookById. createWebhook, updateWebhook and deleteWebhook remain. +- Removed test/test.settings.node.ts and simplified test/test.webhook.node.ts to only exercise create/update/delete webhook flows without feature-availability guarding. +- Stripped console.error debug logging across multiple classes (Author, Ghost, Member, Page, Post, Tag) to reduce noisy runtime output. +- Updated README: removed 'Site Settings' section and clarified webhook API limitations supported by the underlying Ghost Admin SDK. + ## 2025-10-07 - 1.4.1 - fix(tests) Remove updated_at from post and page update test payloads diff --git a/readme.md b/readme.md index 2c344e3..f397b82 100644 --- a/readme.md +++ b/readme.md @@ -404,42 +404,11 @@ await newMember.update({ await newMember.delete(); ``` -#### Site Settings - -Read and update Ghost site settings. - -```typescript -// Get all settings -const settings = await ghostInstance.getSettings(); -console.log(settings); - -// Update settings -await ghostInstance.updateSettings([ - { - key: 'title', - value: 'My Updated Site Title' - }, - { - key: 'description', - value: 'My site description' - } -]); -``` - #### Webhooks Management -Manage webhooks for Ghost events. +Manage webhooks for Ghost events. Note: The Ghost Admin API only supports creating, updating, and deleting webhooks (browsing and reading individual webhooks are not supported by the underlying SDK). ```typescript -// Get all webhooks -const webhooks = await ghostInstance.getWebhooks(); -webhooks.forEach(webhook => { - console.log(`${webhook.name}: ${webhook.target_url}`); -}); - -// Get webhook by ID -const webhook = await ghostInstance.getWebhookById('webhook-id'); - // Create a webhook const newWebhook = await ghostInstance.createWebhook({ event: 'post.published', diff --git a/test/test.settings.node.ts b/test/test.settings.node.ts deleted file mode 100644 index 4b1a3de..0000000 --- a/test/test.settings.node.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { expect, tap } from '@push.rocks/tapbundle'; -import * as qenv from '@push.rocks/qenv'; -const testQenv = new qenv.Qenv('./', './.nogit/'); - -import * as ghost from '../ts/index.js'; - -let testGhostInstance: ghost.Ghost; - -tap.test('initialize Ghost instance', async () => { - testGhostInstance = new ghost.Ghost({ - baseUrl: 'http://localhost:2368', - adminApiKey: await testQenv.getEnvVarOnDemand('ADMIN_APIKEY'), - contentApiKey: await testQenv.getEnvVarOnDemand('CONTENT_APIKEY'), - }); - expect(testGhostInstance).toBeInstanceOf(ghost.Ghost); -}); - -tap.test('should get settings', async () => { - try { - const settings = await testGhostInstance.getSettings(); - expect(settings).toBeTruthy(); - console.log(`Retrieved ${settings.settings?.length || 0} settings`); - if (settings.settings && settings.settings.length > 0) { - console.log(`Sample setting: ${settings.settings[0].key}`); - } - } catch (error: any) { - if (error.message?.includes('undefined') || error.statusCode === 403) { - console.log('Settings API not available in this Ghost version - skipping test'); - } else { - throw error; - } - } -}); - -tap.test('should update settings', async () => { - try { - const settings = await testGhostInstance.getSettings(); - if (settings.settings && settings.settings.length > 0) { - const titleSetting = settings.settings.find((s: any) => s.key === 'title'); - if (titleSetting) { - const originalTitle = titleSetting.value; - - const updated = await testGhostInstance.updateSettings([ - { - key: 'title', - value: originalTitle - } - ]); - expect(updated).toBeTruthy(); - console.log('Settings updated successfully'); - } - } - } catch (error: any) { - if (error.message?.includes('undefined') || error.statusCode === 403) { - console.log('Settings API not available - skipping test'); - } else { - throw error; - } - } -}); - -export default tap.start(); diff --git a/test/test.webhook.node.ts b/test/test.webhook.node.ts index b4030bb..000a1a0 100644 --- a/test/test.webhook.node.ts +++ b/test/test.webhook.node.ts @@ -16,91 +16,26 @@ tap.test('initialize Ghost instance', async () => { expect(testGhostInstance).toBeInstanceOf(ghost.Ghost); }); -tap.test('should get all webhooks', async () => { - try { - const webhooks = await testGhostInstance.getWebhooks(); - expect(webhooks).toBeArray(); - console.log(`Found ${webhooks.length} webhooks`); - if (webhooks.length > 0) { - console.log(`First webhook: ${webhooks[0].name || 'unnamed'}`); - } - } catch (error: any) { - if (error.message?.includes('not a function') || error.statusCode === 403) { - console.log('Webhooks API not available in this Ghost version - skipping test'); - } else { - throw error; - } - } -}); - tap.test('should create webhook', async () => { - try { - const timestamp = Date.now(); - createdWebhook = await testGhostInstance.createWebhook({ - event: 'post.published', - target_url: `https://example.com/webhook/${timestamp}`, - name: `Test Webhook ${timestamp}` - }); - expect(createdWebhook).toBeTruthy(); - expect(createdWebhook.id).toBeTruthy(); - console.log(`Created webhook: ${createdWebhook.id}`); - } catch (error: any) { - if (error.message?.includes('not a function') || error.statusCode === 403) { - console.log('Webhooks API not available - skipping test'); - } else { - throw error; - } - } -}); - -tap.test('should get webhook by ID', async () => { - if (createdWebhook) { - try { - const webhook = await testGhostInstance.getWebhookById(createdWebhook.id); - expect(webhook).toBeTruthy(); - expect(webhook.id).toEqual(createdWebhook.id); - console.log(`Got webhook by ID: ${webhook.id}`); - } catch (error: any) { - if (error.message?.includes('not a function') || error.statusCode === 403) { - console.log('Webhooks API not available - skipping test'); - } else { - throw error; - } - } - } + const timestamp = Date.now(); + createdWebhook = await testGhostInstance.createWebhook({ + event: 'post.published', + target_url: `https://example.com/webhook/${timestamp}`, + name: `Test Webhook ${timestamp}` + }); + expect(createdWebhook).toBeTruthy(); + expect(createdWebhook.id).toBeTruthy(); }); tap.test('should update webhook', async () => { - if (createdWebhook) { - try { - const updatedWebhook = await testGhostInstance.updateWebhook(createdWebhook.id, { - target_url: 'https://example.com/webhook/updated' - }); - expect(updatedWebhook).toBeTruthy(); - console.log(`Updated webhook: ${updatedWebhook.id}`); - } catch (error: any) { - if (error.message?.includes('not a function') || error.statusCode === 403) { - console.log('Webhooks API not available - skipping test'); - } else { - throw error; - } - } - } + const updatedWebhook = await testGhostInstance.updateWebhook(createdWebhook.id, { + target_url: 'https://example.com/webhook/updated' + }); + expect(updatedWebhook).toBeTruthy(); }); tap.test('should delete webhook', async () => { - if (createdWebhook) { - try { - await testGhostInstance.deleteWebhook(createdWebhook.id); - console.log(`Deleted webhook: ${createdWebhook.id}`); - } catch (error: any) { - if (error.message?.includes('not a function') || error.statusCode === 403) { - console.log('Webhooks API not available - skipping test'); - } else { - throw error; - } - } - } + await testGhostInstance.deleteWebhook(createdWebhook.id); }); export default tap.start(); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 29f218f..c4dfa7a 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@apiclient.xyz/ghost', - version: '1.4.1', + version: '2.0.0', description: 'An unofficial Ghost CMS API package enabling content and admin functionality for managing posts.' } diff --git a/ts/classes.author.ts b/ts/classes.author.ts index 35533ce..dd26cfd 100644 --- a/ts/classes.author.ts +++ b/ts/classes.author.ts @@ -43,7 +43,6 @@ export class Author { this.authorData = updatedAuthorData; return this; } catch (error) { - console.error('Error updating author:', error); throw error; } } diff --git a/ts/classes.ghost.ts b/ts/classes.ghost.ts index 8fdfd52..b7785df 100644 --- a/ts/classes.ghost.ts +++ b/ts/classes.ghost.ts @@ -65,7 +65,6 @@ export class Ghost { }); return postsData.map((postData: IPost) => new Post(this, postData)); } catch (error) { - console.error('Error fetching posts:', error); throw error; } } @@ -75,7 +74,6 @@ export class Ghost { const postData = await this.contentApi.posts.read({ id }); return new Post(this, postData); } catch (error) { - console.error(`Error fetching post with id ${id}:`, error); throw error; } } @@ -85,7 +83,6 @@ export class Ghost { const createdPostData = await this.adminApi.posts.add(postData); return new Post(this, createdPostData); } catch (error) { - console.error('Error creating post:', error); throw error; } } @@ -110,7 +107,6 @@ export class Ghost { return tagsData; } catch (error) { - console.error('Error fetching tags:', error); throw error; } } @@ -120,7 +116,6 @@ export class Ghost { const tagData = await this.contentApi.tags.read({ id }); return new Tag(this, tagData); } catch (error) { - console.error(`Error fetching tag with id ${id}:`, error); throw error; } } @@ -130,7 +125,6 @@ export class Ghost { const tagData = await this.contentApi.tags.read({ slug }); return new Tag(this, tagData); } catch (error) { - console.error(`Error fetching tag with slug ${slug}:`, error); throw error; } } @@ -140,7 +134,6 @@ export class Ghost { const createdTagData = await this.adminApi.tags.add(tagData); return new Tag(this, createdTagData); } catch (error) { - console.error('Error creating tag:', error); throw error; } } @@ -159,7 +152,6 @@ export class Ghost { return authorsData.map((author: IAuthor) => new Author(this, author)); } catch (error) { - console.error('Error fetching authors:', error); throw error; } } @@ -169,7 +161,6 @@ export class Ghost { const authorData = await this.contentApi.authors.read({ id }); return new Author(this, authorData); } catch (error) { - console.error(`Error fetching author with id ${id}:`, error); throw error; } } @@ -179,7 +170,6 @@ export class Ghost { const authorData = await this.contentApi.authors.read({ slug }); return new Author(this, authorData); } catch (error) { - console.error(`Error fetching author with slug ${slug}:`, error); throw error; } } @@ -198,7 +188,6 @@ export class Ghost { return pagesData.map((pageData: IPage) => new Page(this, pageData)); } catch (error) { - console.error('Error fetching pages:', error); throw error; } } @@ -208,7 +197,6 @@ export class Ghost { const pageData = await this.contentApi.pages.read({ id }); return new Page(this, pageData); } catch (error) { - console.error(`Error fetching page with id ${id}:`, error); throw error; } } @@ -218,7 +206,6 @@ export class Ghost { const pageData = await this.contentApi.pages.read({ slug }); return new Page(this, pageData); } catch (error) { - console.error(`Error fetching page with slug ${slug}:`, error); throw error; } } @@ -228,7 +215,6 @@ export class Ghost { const createdPageData = await this.adminApi.pages.add(pageData); return new Page(this, createdPageData); } catch (error) { - console.error('Error creating page:', error); throw error; } } @@ -243,7 +229,6 @@ export class Ghost { }); return postsData.map((postData: IPost) => new Post(this, postData)); } catch (error) { - console.error('Error searching posts:', error); throw error; } } @@ -253,7 +238,6 @@ export class Ghost { const result = await this.adminApi.images.upload({ file: filePath }); return result.url; } catch (error) { - console.error('Error uploading image:', error); throw error; } } @@ -266,7 +250,6 @@ export class Ghost { }); return await Promise.all(updatePromises); } catch (error) { - console.error('Error bulk updating posts:', error); throw error; } } @@ -279,7 +262,6 @@ export class Ghost { }); await Promise.all(deletePromises); } catch (error) { - console.error('Error bulk deleting posts:', error); throw error; } } @@ -302,7 +284,6 @@ export class Ghost { return postsData.map((postData: IPost) => new Post(this, postData)); } catch (error) { - console.error('Error fetching related posts:', error); throw error; } } @@ -321,7 +302,6 @@ export class Ghost { return membersData.map((member: IMember) => new Member(this, member)); } catch (error) { - console.error('Error fetching members:', error); throw error; } } @@ -331,7 +311,6 @@ export class Ghost { 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; } } @@ -341,7 +320,6 @@ export class Ghost { 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; } } @@ -351,43 +329,6 @@ export class Ghost { 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 { - try { - return await this.adminApi.settings.browse(); - } catch (error) { - console.error('Error fetching settings:', error); - throw error; - } - } - - public async updateSettings(settings: any[]): Promise { - try { - return await this.adminApi.settings.edit(settings); - } catch (error) { - console.error('Error updating settings:', error); - throw error; - } - } - - public async getWebhooks(): Promise { - try { - return await this.adminApi.webhooks.browse(); - } catch (error) { - console.error('Error fetching webhooks:', error); - throw error; - } - } - - public async getWebhookById(id: string): Promise { - try { - return await this.adminApi.webhooks.read({ id }); - } catch (error) { - console.error(`Error fetching webhook with id ${id}:`, error); throw error; } } @@ -403,7 +344,6 @@ export class Ghost { try { return await this.adminApi.webhooks.add(webhookData); } catch (error) { - console.error('Error creating webhook:', error); throw error; } } @@ -412,7 +352,6 @@ export class Ghost { try { return await this.adminApi.webhooks.edit({ ...webhookData, id }); } catch (error) { - console.error('Error updating webhook:', error); throw error; } } @@ -421,7 +360,6 @@ export class Ghost { try { await this.adminApi.webhooks.delete({ id }); } catch (error) { - console.error(`Error deleting webhook with id ${id}:`, error); throw error; } } diff --git a/ts/classes.member.ts b/ts/classes.member.ts index 994d432..26a0c0d 100644 --- a/ts/classes.member.ts +++ b/ts/classes.member.ts @@ -71,7 +71,6 @@ export class Member { this.memberData = updatedMemberData; return this; } catch (error) { - console.error('Error updating member:', error); throw error; } } @@ -80,7 +79,6 @@ export class Member { try { await this.ghostInstanceRef.adminApi.members.delete({ id: this.getId() }); } catch (error) { - console.error(`Error deleting member with id ${this.getId()}:`, error); throw error; } } diff --git a/ts/classes.page.ts b/ts/classes.page.ts index c3f6e98..7fdfdb1 100644 --- a/ts/classes.page.ts +++ b/ts/classes.page.ts @@ -49,7 +49,6 @@ export class Page { this.pageData = updatedPageData; return this; } catch (error) { - console.error('Error updating page:', error); throw error; } } @@ -58,7 +57,6 @@ export class Page { try { await this.ghostInstanceRef.adminApi.pages.delete({ id: this.getId() }); } catch (error) { - console.error(`Error deleting page with id ${this.getId()}:`, error); throw error; } } diff --git a/ts/classes.post.ts b/ts/classes.post.ts index 824873e..b3c9ef0 100644 --- a/ts/classes.post.ts +++ b/ts/classes.post.ts @@ -124,7 +124,6 @@ export class Post { this.postData = updatedPostData; return this; } catch (error) { - console.error('Error updating post:', error); throw error; } } @@ -133,7 +132,6 @@ export class Post { try { await this.ghostInstanceRef.adminApi.posts.delete({ id: this.getId() }); } catch (error) { - console.error(`Error deleting post with id ${this.getId()}:`, error); throw error; } } diff --git a/ts/classes.tag.ts b/ts/classes.tag.ts index 9228e67..41d94ef 100644 --- a/ts/classes.tag.ts +++ b/ts/classes.tag.ts @@ -39,7 +39,6 @@ export class Tag { this.tagData = updatedTagData; return this; } catch (error) { - console.error('Error updating tag:', error); throw error; } } @@ -48,7 +47,6 @@ export class Tag { try { await this.ghostInstanceRef.adminApi.tags.delete({ id: this.getId() }); } catch (error) { - console.error(`Error deleting tag with id ${this.getId()}:`, error); throw error; } }