diff --git a/apps/admin-x-settings/package.json b/apps/admin-x-settings/package.json index f70b89a5f84..0c86f88db4e 100644 --- a/apps/admin-x-settings/package.json +++ b/apps/admin-x-settings/package.json @@ -42,7 +42,7 @@ "@codemirror/lang-html": "6.4.11", "@tryghost/color-utils": "0.2.10", "@tryghost/i18n": "0.0.0", - "@tryghost/kg-unsplash-selector": "0.3.6", + "@tryghost/kg-unsplash-selector": "0.3.10", "@tryghost/limit-service": "1.4.1", "@tryghost/nql": "0.12.7", "@tryghost/timezone-data": "0.4.12", @@ -84,4 +84,4 @@ } } } -} \ No newline at end of file +} diff --git a/apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx b/apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx index 39e2cbdc77b..17df2c245bb 100644 --- a/apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx +++ b/apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx @@ -67,6 +67,10 @@ const features: Feature[] = [{ title: 'Featurebase Feedback', description: 'Display a Feedback menu item in the admin sidebar. Requires the new admin experience.', flag: 'featurebaseFeedback' +}, { + title: 'Transistor', + description: 'Enable Transistor podcast integration', + flag: 'transistor' }]; const AlphaFeatures: React.FC = () => { diff --git a/apps/admin/package.json b/apps/admin/package.json index cccb731f8dc..616a42faae6 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -15,7 +15,7 @@ "@tryghost/activitypub": "*", "@tryghost/admin-x-framework": "*", "@tryghost/admin-x-settings": "*", - "@tryghost/koenig-lexical": "1.7.2", + "@tryghost/koenig-lexical": "1.7.6", "@tryghost/posts": "*", "@tryghost/shade": "*", "@tryghost/stats": "*", diff --git a/apps/posts/src/views/comments/comments.tsx b/apps/posts/src/views/comments/comments.tsx index 8a303757b3e..2ac39d377f1 100644 --- a/apps/posts/src/views/comments/comments.tsx +++ b/apps/posts/src/views/comments/comments.tsx @@ -11,7 +11,7 @@ import {useFilterState} from './hooks/use-filter-state'; import {useKnownFilterValues} from './hooks/use-known-filter-values'; const Comments: React.FC = () => { - const {filters, nql, setFilters} = useFilterState(); + const {filters, nql, setFilters, clearFilters, isSingleIdFilter} = useFilterState(); const {data: configData} = useBrowseConfig(); const commentPermalinksEnabled = configData?.config?.labs?.commentPermalinks === true; @@ -23,7 +23,7 @@ const Comments: React.FC = () => { return [...filtered, createFilter(field, operator, [value])]; }, {replace: false}); }, [setFilters]); - + const { data, isError, @@ -41,12 +41,14 @@ const Comments: React.FC = () => { return ( - + {!isSingleIdFilter && ( + + )} {(isFetching && !isFetchingNextPage) ? ( @@ -74,16 +76,25 @@ const Comments: React.FC = () => { ) : ( - + <> + + {isSingleIdFilter && ( +
+ +
+ )} + )}
diff --git a/apps/posts/src/views/comments/hooks/use-filter-state.ts b/apps/posts/src/views/comments/hooks/use-filter-state.ts index f5d1f86ef9f..2ad2a88c85d 100644 --- a/apps/posts/src/views/comments/hooks/use-filter-state.ts +++ b/apps/posts/src/views/comments/hooks/use-filter-state.ts @@ -5,24 +5,28 @@ import type {Filter} from '@tryghost/shade'; /** * Comment filter field keys - single source of truth for filter definitions */ -export const COMMENT_FILTER_FIELDS = ['status', 'created_at', 'body', 'post', 'author', 'reported'] as const; +export const COMMENT_FILTER_FIELDS = ['id', 'status', 'created_at', 'body', 'post', 'author', 'reported'] as const; export type CommentFilterField = typeof COMMENT_FILTER_FIELDS[number]; export function buildNqlFilter(filters: Filter[]): string | undefined { const parts: string[] = []; - + for (const filter of filters) { if (!filter.values[0]) { continue; } switch (filter.field) { - case 'status': + case 'id': + parts.push(`id:'${filter.values[0]}'`); + break; + + case 'status': parts.push(`status:${filter.values[0]}`); break; - case 'created_at': + case 'created_at': if (filter.operator === 'before' && filter.values[0]) { parts.push(`created_at:<'${filter.values[0]}'`); } else if (filter.operator === 'after' && filter.values[0]) { @@ -30,20 +34,20 @@ export function buildNqlFilter(filters: Filter[]): string | undefined { } else if (filter.operator === 'is' && filter.values[0]) { // Match all items from the selected day in the user's timezone const dateValue = String(filter.values[0]); // Format: YYYY-MM-DD - + // Create Date objects in user's local timezone, then convert to UTC const startOfDay = new Date(dateValue + 'T00:00:00').toISOString(); const endOfDay = new Date(dateValue + 'T23:59:59.999').toISOString(); - + parts.push(`created_at:>='${startOfDay}'+created_at:<='${endOfDay}'`); } break; - case 'body': + case 'body': const value = filter.values[0] as string; // Escape single quotes in the value const escapedValue = value.replace(/'/g, '\\\''); - + if (filter.operator === 'contains') { parts.push(`html:~'${escapedValue}'`); } else if (filter.operator === 'not_contains') { @@ -51,7 +55,7 @@ export function buildNqlFilter(filters: Filter[]): string | undefined { } break; - case 'post': + case 'post': if (filter.operator === 'is_not') { parts.push(`post_id:-${filter.values[0]}`); } else { @@ -60,7 +64,7 @@ export function buildNqlFilter(filters: Filter[]): string | undefined { } break; - case 'author': + case 'author': if (filter.operator === 'is_not') { parts.push(`member_id:-${filter.values[0]}`); } else { @@ -78,7 +82,7 @@ export function buildNqlFilter(filters: Filter[]): string | undefined { break; } } - + return parts.length ? parts.join('+') : undefined; } /** @@ -150,16 +154,23 @@ interface SetFiltersOptions { replace?: boolean; } +interface ClearFiltersOptions { + /** Whether to replace the current history entry (default: true) */ + replace?: boolean; +} + interface UseFilterStateReturn { filters: Filter[]; nql: string | undefined; setFilters: (action: SetFiltersAction, options?: SetFiltersOptions) => void; - clearFilters: () => void; + clearFilters: (options?: ClearFiltersOptions) => void; + /** True when the only active filter is a single comment ID (used for deep linking) */ + isSingleIdFilter: boolean; } /** * Hook to sync comment filter state with URL query parameters - * + * * URL format: ?status=is:published&author=is:member-id&body=contains:search+term */ export function useFilterState(): UseFilterStateReturn { @@ -181,11 +192,16 @@ export function useFilterState(): UseFilterStateReturn { }, [filters, setSearchParams]); // Clear all filter params from URL - const clearFilters = useCallback(() => { - setSearchParams(new URLSearchParams(), {replace: true}); + const clearFilters = useCallback(({replace = true}: {replace?: boolean} = {}) => { + setSearchParams(new URLSearchParams(), {replace}); }, [setSearchParams]); const nql = useMemo(() => buildNqlFilter(filters), [filters]); - return {filters, nql, setFilters, clearFilters}; + // Check if the only active filter is a single comment ID (used for deep linking) + const isSingleIdFilter = useMemo(() => { + return filters.length === 1 && filters[0].field === 'id'; + }, [filters]); + + return {filters, nql, setFilters, clearFilters, isSingleIdFilter}; } diff --git a/e2e/tests/admin/comments/comment-moderation.test.ts b/e2e/tests/admin/comments/comment-moderation.test.ts index db873abfeb5..6c1cf64d0c8 100644 --- a/e2e/tests/admin/comments/comment-moderation.test.ts +++ b/e2e/tests/admin/comments/comment-moderation.test.ts @@ -75,4 +75,44 @@ test.describe('Ghost Admin - Comment Moderation', () => { await expect(postPage).toHaveURL(new RegExp(`/${post.slug}/.*#ghost-comments-${comment.id}`)); }); }); + + test.describe('deep linking', () => { + test.use({labs: {commentModeration: true}}); + + test('can deep link to a specific comment by id', async ({page}) => { + const post = await postFactory.create({status: 'published'}); + const member = await memberFactory.create(); + + // Create target comment and another comment + const targetComment = await commentFactory.create({ + post_id: post.id, + member_id: member.id, + html: '

This is the target comment

' + }); + await commentFactory.create({ + post_id: post.id, + member_id: member.id, + html: '

This is another comment

' + }); + + const commentsPage = new CommentsPage(page); + await page.goto(`/ghost/#/comments?id=is:${targetComment.id}`); + await commentsPage.waitForComments(); + + await expect(commentsPage.getCommentRowByText('This is the target comment')).toBeVisible(); + await expect(commentsPage.getCommentRowByText('This is another comment')).not.toBeVisible(); + + await expect(page.getByRole('button', {name: 'Filter'})).not.toBeVisible(); + + const showAllButton = page.getByRole('button', {name: 'Show all comments'}); + await expect(showAllButton).toBeVisible(); + + await showAllButton.click(); + await expect(commentsPage.getCommentRowByText('This is the target comment')).toBeVisible(); + await expect(commentsPage.getCommentRowByText('This is another comment')).toBeVisible(); + + await expect(page.getByRole('button', {name: 'Filter'})).toBeVisible(); + await expect(showAllButton).not.toBeVisible(); + }); + }); }); diff --git a/ghost/admin/package.json b/ghost/admin/package.json index cea52f5be19..f62ae31f5fb 100644 --- a/ghost/admin/package.json +++ b/ghost/admin/package.json @@ -1,6 +1,6 @@ { "name": "ghost-admin", - "version": "6.12.1", + "version": "6.13.1", "description": "Ember.js admin client for Ghost", "author": "Ghost Foundation", "homepage": "http://ghost.org", @@ -47,9 +47,9 @@ "@tryghost/color-utils": "0.2.10", "@tryghost/ember-promise-modals": "2.0.1", "@tryghost/helpers": "1.1.97", - "@tryghost/kg-clean-basic-html": "4.2.7", - "@tryghost/kg-converters": "1.1.7", - "@tryghost/koenig-lexical": "1.7.2", + "@tryghost/kg-clean-basic-html": "4.2.11", + "@tryghost/kg-converters": "1.1.11", + "@tryghost/koenig-lexical": "1.7.6", "@tryghost/limit-service": "1.4.1", "@tryghost/members-csv": "2.0.3", "@tryghost/nql": "0.12.7", @@ -215,4 +215,4 @@ } } } -} \ No newline at end of file +} diff --git a/ghost/core/core/server/services/comments/comments-service-emails.js b/ghost/core/core/server/services/comments/comments-service-emails.js index 98038e9e617..24fc52d9803 100644 --- a/ghost/core/core/server/services/comments/comments-service-emails.js +++ b/ghost/core/core/server/services/comments/comments-service-emails.js @@ -154,6 +154,8 @@ class CommentsServiceEmails { const memberName = member.get('name') || 'Anonymous'; + const commentModerationEnabled = this.labs.isSet('commentModeration'); + const templateData = { siteTitle: this.settingsCache.get('title'), siteUrl: this.urlUtils.getSiteUrl(), @@ -175,7 +177,9 @@ class CommentsServiceEmails { accentColor: this.settingsCache.get('accent_color'), fromEmail: this.notificationFromAddress, toEmail: to, - staffUrl: this.urlUtils.urlJoin(this.urlUtils.urlFor('admin', true), '#', `/settings/staff/${owner.get('slug')}/email-notifications`) + staffUrl: this.urlUtils.urlJoin(this.urlUtils.urlFor('admin', true), '#', `/settings/staff/${owner.get('slug')}/email-notifications`), + commentModerationEnabled, + moderationUrl: this.urlUtils.urlJoin(this.urlUtils.urlFor('admin', true), '#', `/comments/?id=is:${comment.get('id')}`) }; const {html, text} = await this.commentsServiceEmailRenderer.renderEmailTemplate('report', templateData); diff --git a/ghost/core/core/server/services/comments/email-templates/report.hbs b/ghost/core/core/server/services/comments/email-templates/report.hbs index 2f594c93c2c..45d19c25689 100644 --- a/ghost/core/core/server/services/comments/email-templates/report.hbs +++ b/ghost/core/core/server/services/comments/email-templates/report.hbs @@ -116,7 +116,7 @@

Hey there,

-

{{reporter}} has reported the comment below on {{postTitle}}. This comment will remain visible until you choose to remove it, which can be done directly on the post.

+

{{reporter}} has reported the comment below on {{postTitle}}.{{#unless commentModerationEnabled}} This comment will remain visible until you choose to remove it, which can be done directly on the post.{{/unless}}

@@ -152,7 +152,11 @@
+ {{#if commentModerationEnabled}} + + {{else}} + {{/if}}
Review comment View comment
diff --git a/ghost/core/core/server/services/comments/email-templates/report.txt.js b/ghost/core/core/server/services/comments/email-templates/report.txt.js index 807ce9d00ed..49d7db55bb3 100644 --- a/ghost/core/core/server/services/comments/email-templates/report.txt.js +++ b/ghost/core/core/server/services/comments/email-templates/report.txt.js @@ -1,13 +1,22 @@ module.exports = function (data) { + let visibilityNote = 'This comment will remain visible until you choose to remove it.'; + if (!data.commentModerationEnabled) { + visibilityNote = 'This comment will remain visible until you choose to remove it, which can be done directly on the post.'; + } + + let actionLinks = data.postUrl; + if (data.commentModerationEnabled) { + actionLinks = `View comment: ${data.postUrl}\nModerate comment: ${data.moderationUrl}`; + } + // Be careful when you indent the email, because whitespaces are visible in emails! return `Hey there, -${data.reporter} has reported the comment below on ${data.postTitle}. This comment will remain visible until you choose to remove it, which can be done directly on the post. +${data.reporter} has reported the comment below on ${data.postTitle}. ${visibilityNote} ${data.memberName} (${data.memberEmail}): ${data.commentText} - -${data.postUrl} +${actionLinks} --- diff --git a/ghost/core/core/shared/labs.js b/ghost/core/core/shared/labs.js index 37d77bde382..962c1e3cec3 100644 --- a/ghost/core/core/shared/labs.js +++ b/ghost/core/core/shared/labs.js @@ -57,7 +57,8 @@ const PRIVATE_FEATURES = [ 'commentModeration', 'commentPermalinks', 'indexnow', - 'featurebaseFeedback' + 'featurebaseFeedback', + 'transistor' ]; module.exports.GA_KEYS = [...GA_FEATURES]; diff --git a/ghost/core/package.json b/ghost/core/package.json index 8cd2792ae3d..17ae80ea262 100644 --- a/ghost/core/package.json +++ b/ghost/core/package.json @@ -1,6 +1,6 @@ { "name": "ghost", - "version": "6.12.1", + "version": "6.13.1", "description": "The professional publishing platform", "author": "Ghost Foundation", "homepage": "https://ghost.org", @@ -86,17 +86,17 @@ "@tryghost/i18n": "0.0.0", "@tryghost/image-transform": "1.4.6", "@tryghost/job-manager": "1.0.3", - "@tryghost/kg-card-factory": "5.1.2", + "@tryghost/kg-card-factory": "5.1.6", "@tryghost/kg-clean-basic-html": "4.2.7", - "@tryghost/kg-converters": "1.1.7", + "@tryghost/kg-converters": "1.1.11", "@tryghost/kg-default-atoms": "5.1.1", - "@tryghost/kg-default-cards": "10.2.2", - "@tryghost/kg-default-nodes": "2.0.1", - "@tryghost/kg-default-transforms": "1.2.24", - "@tryghost/kg-html-to-lexical": "1.2.24", - "@tryghost/kg-lexical-html-renderer": "1.3.24", - "@tryghost/kg-markdown-html-renderer": "7.1.3", - "@tryghost/kg-mobiledoc-html-renderer": "7.1.3", + "@tryghost/kg-default-cards": "10.2.3", + "@tryghost/kg-default-nodes": "2.0.5", + "@tryghost/kg-default-transforms": "1.2.28", + "@tryghost/kg-html-to-lexical": "1.2.28", + "@tryghost/kg-lexical-html-renderer": "1.3.28", + "@tryghost/kg-markdown-html-renderer": "7.1.7", + "@tryghost/kg-mobiledoc-html-renderer": "7.1.7", "@tryghost/limit-service": "1.4.1", "@tryghost/logging": "2.5.0", "@tryghost/members-csv": "2.0.3", @@ -217,7 +217,7 @@ "xml": "1.0.1" }, "optionalDependencies": { - "@tryghost/html-to-mobiledoc": "3.2.8", + "@tryghost/html-to-mobiledoc": "3.2.12", "sqlite3": "5.1.7" }, "devDependencies": { diff --git a/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap b/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap index ae43d719ca5..187e79fc435 100644 --- a/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap +++ b/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap @@ -34,6 +34,7 @@ Object { "tagsX": true, "themeErrorsNotification": true, "themeTranslation": true, + "transistor": true, "urlCache": true, "utmTracking": true, "webmentions": true, diff --git a/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap b/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost-head.test.js.snap similarity index 100% rename from ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap rename to ghost/core/test/unit/frontend/helpers/__snapshots__/ghost-head.test.js.snap diff --git a/yarn.lock b/yarn.lock index 38857a2d281..5273d578024 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8987,12 +8987,12 @@ dependencies: lodash-es "^4.17.11" -"@tryghost/html-to-mobiledoc@3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@tryghost/html-to-mobiledoc/-/html-to-mobiledoc-3.2.8.tgz#8ff8744c022c0b0d9bf678015da497294e4c08bc" - integrity sha512-qQ/5ysa7jDny+GWYrwH5OEJqezRm0ed5k/1oe7Un1csaW2qQVQX/DeXD8j6jcJOccSRr2ISe2V1Ts4FdibsM4Q== +"@tryghost/html-to-mobiledoc@3.2.12": + version "3.2.12" + resolved "https://registry.yarnpkg.com/@tryghost/html-to-mobiledoc/-/html-to-mobiledoc-3.2.12.tgz#9caa23074c58bb796fabd17f88ef70b57469613e" + integrity sha512-xGrYmrEvDhcjK41SHjYoKKNjMVd2Kip3GMLy8TE4+Ev++dH7/wUzFXDIqM8sOgg5duNVCGB6Bhv+ALkHvZeKIA== dependencies: - "@tryghost/kg-parser-plugins" "4.2.7" + "@tryghost/kg-parser-plugins" "4.2.11" "@tryghost/mobiledoc-kit" "^0.12.4-ghost.1" jsdom "^24.1.1" @@ -9051,20 +9051,25 @@ p-wait-for "3.2.0" workerpool "9.3.3" -"@tryghost/kg-card-factory@5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@tryghost/kg-card-factory/-/kg-card-factory-5.1.2.tgz#9a8a34e4a9da0e40e6aebae21bbc2f1a3ce20454" - integrity sha512-mrseuYlQMB92NbPQCgN8hnlxYpckkAFEK+3oovoKwUzsOD7WAColt/QCSOZXYKIkKbact7vO11UFAES2fqQOUw== +"@tryghost/kg-card-factory@5.1.6": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@tryghost/kg-card-factory/-/kg-card-factory-5.1.6.tgz#6aa274cb596c9961a4051f26eb3c9097a278fe5f" + integrity sha512-zHcIiCR4RF/nRIvAMxEmDSnIjyd4sjN9z+11vqRW/7XDCzIw0P2AU06dowztt1xRmvZvAdTwVWXG2fBbDv5JCw== + +"@tryghost/kg-clean-basic-html@4.2.11": + version "4.2.11" + resolved "https://registry.yarnpkg.com/@tryghost/kg-clean-basic-html/-/kg-clean-basic-html-4.2.11.tgz#62d0271e9c02a1212c27fe93874da63152ed013f" + integrity sha512-XiztZr53NbSI2hiFJx6bLiSIW66/qz0jAPaRpUs1cxFERwnnzl0KtMGnukcx2DWIrggbBpDGYRKctHY/zQJrew== "@tryghost/kg-clean-basic-html@4.2.7": version "4.2.7" resolved "https://registry.yarnpkg.com/@tryghost/kg-clean-basic-html/-/kg-clean-basic-html-4.2.7.tgz#da0ef755934e396a8a52b520ed089e6337b2f3a2" integrity sha512-pScSO2SdMCuPM9o4Vbgaf1AkZjk3Jt6F/VE2v2MZkJ4kv5yA8s74P/muuLR1NKh1y7/YEpoGLPSVTRzU0TrCpQ== -"@tryghost/kg-converters@1.1.7": - version "1.1.7" - resolved "https://registry.yarnpkg.com/@tryghost/kg-converters/-/kg-converters-1.1.7.tgz#5cbbeed07f06d687166ddb28de2b0e3e87670e25" - integrity sha512-klln6/DBXSaeNoVbb2cQQsCPktk3BxdZvkOhcu02vWp/fzl/EUTVPJ0kbCiCL2j8LrTDbXKLYnasWoU9yIe7Kw== +"@tryghost/kg-converters@1.1.11": + version "1.1.11" + resolved "https://registry.yarnpkg.com/@tryghost/kg-converters/-/kg-converters-1.1.11.tgz#89e22ea37e6696b720f67b14afc92db7d94d9412" + integrity sha512-ZWVcZmTFBqKf/LcIBBFtWvcodeoU+bj5r2I6dq0NvcNVtpoTvdCY6ylPOJ4KUO6j+whwZRLNvYsnoq+Db4TCAA== dependencies: lodash "^4.17.21" @@ -9073,12 +9078,12 @@ resolved "https://registry.yarnpkg.com/@tryghost/kg-default-atoms/-/kg-default-atoms-5.1.1.tgz#de490aa9847294ee7de70be816ce21e6b8737f1b" integrity sha512-VeQOz36U6J+ZNcgiDSJI+qu7MO2ORN8YtDsZoFxhH/EilCHAGWBURgv2qfx3AP4ScI4KCx+cBjt6gm+u1aYI5A== -"@tryghost/kg-default-cards@10.2.2": - version "10.2.2" - resolved "https://registry.yarnpkg.com/@tryghost/kg-default-cards/-/kg-default-cards-10.2.2.tgz#083bd07af674cf863c8e886fd9e2e6bf247d39d2" - integrity sha512-OKJvIRNZJSqvPaldUETRqL7fG4ITvrmSc4K9zPHT0v7JDGAUyD67TnCaOyzWp1SVTMOUURqKRi0oYV4ZPIsWWA== +"@tryghost/kg-default-cards@10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@tryghost/kg-default-cards/-/kg-default-cards-10.2.3.tgz#62514f6a3633bd8c177fc15d6283a71c6e4ec34e" + integrity sha512-gMccb5uo0f3i44duPT852YhXMT/p2rGW9L6VTBbw2PwVTanSS4D7T+zXAQgvXo/ITkNkCHDngSQt+iFsjCQf3A== dependencies: - "@tryghost/kg-markdown-html-renderer" "7.1.6" + "@tryghost/kg-markdown-html-renderer" "7.1.7" "@tryghost/string" "0.2.17" "@tryghost/url-utils" "5.1.0" handlebars "^4.7.6" @@ -9086,16 +9091,16 @@ lodash "^4.17.21" luxon "^3.5.0" -"@tryghost/kg-default-nodes@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@tryghost/kg-default-nodes/-/kg-default-nodes-2.0.1.tgz#987d7708a8f7395b934d4d5e849a594484b87150" - integrity sha512-DPO1bvnrnIh7xlHxtnICCbs88qGKeslT0S3MowOtiJ0FG6xRdl1+J0h5JitS38NjQi+HZxSDW75hYdmWvVQfCg== +"@tryghost/kg-default-nodes@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@tryghost/kg-default-nodes/-/kg-default-nodes-2.0.5.tgz#7cada93b90cf934b025199a2b67a8c583b061737" + integrity sha512-YTYDC1FSWgduzLqLDTm6H1ZJj1HGj8fvO0qOVOSA1wLhNLt144PDkoyC+TqdQInPd3xV5EFDccROPFxcty7rNA== dependencies: "@lexical/clipboard" "0.13.1" "@lexical/rich-text" "0.13.1" "@lexical/selection" "0.13.1" "@lexical/utils" "0.13.1" - "@tryghost/kg-clean-basic-html" "4.2.7" + "@tryghost/kg-clean-basic-html" "4.2.11" "@tryghost/kg-markdown-html-renderer" "7.1.2" clsx "2.1.1" html-minifier "^4.0.0" @@ -9104,21 +9109,21 @@ lodash "^4.17.21" luxon "^3.5.0" -"@tryghost/kg-default-transforms@1.2.24": - version "1.2.24" - resolved "https://registry.yarnpkg.com/@tryghost/kg-default-transforms/-/kg-default-transforms-1.2.24.tgz#f539b1b9763d81fc649bc31b9d7798a314b677f8" - integrity sha512-AgoA7nUqAtsVJiROdA1FXvoNr92cNxEDSY4ndPd7nqXP1K2NHX5hqNYb6C2m2vds7lJKA6aXEFJPs+ddpgWS5w== +"@tryghost/kg-default-transforms@1.2.28": + version "1.2.28" + resolved "https://registry.yarnpkg.com/@tryghost/kg-default-transforms/-/kg-default-transforms-1.2.28.tgz#281f3f01acf215c2359a4cf02ef183853a92c83f" + integrity sha512-YiKegt21lOzrQVhHDjCp/zfLu1Wp1gURhi+dC8xgs6xZW/6pmeM/s0voD+qfxB1MKI1cJVtiBGYuI2TPjMnZ0g== dependencies: "@lexical/list" "0.13.1" "@lexical/rich-text" "0.13.1" "@lexical/utils" "0.13.1" - "@tryghost/kg-default-nodes" "2.0.1" + "@tryghost/kg-default-nodes" "2.0.5" lexical "0.13.1" -"@tryghost/kg-html-to-lexical@1.2.24": - version "1.2.24" - resolved "https://registry.yarnpkg.com/@tryghost/kg-html-to-lexical/-/kg-html-to-lexical-1.2.24.tgz#a51c27cb2fc2a77b3bca840ddc036f80bd22162e" - integrity sha512-8XH3a9UiaSK3qludJj6IRJKaPvk9oFBFKSl9PZnnvraP/fVZBiBIERP4MmwYUMHrqAieA1SQx+ueESES+8xSCw== +"@tryghost/kg-html-to-lexical@1.2.28": + version "1.2.28" + resolved "https://registry.yarnpkg.com/@tryghost/kg-html-to-lexical/-/kg-html-to-lexical-1.2.28.tgz#f32cff8e9ccf75375c187ac894fb6acf82821632" + integrity sha512-rgFO1Q55n7f33JWtmX7Mk+dg7m1HslTpOYmx01NxeQPaKN8NrI0jwa5GJsVXsRyorZWqS8czilVOSdJmkp2ReA== dependencies: "@lexical/clipboard" "0.13.1" "@lexical/headless" "0.13.1" @@ -9126,15 +9131,15 @@ "@lexical/link" "0.13.1" "@lexical/list" "0.13.1" "@lexical/rich-text" "0.13.1" - "@tryghost/kg-default-nodes" "2.0.1" - "@tryghost/kg-default-transforms" "1.2.24" + "@tryghost/kg-default-nodes" "2.0.5" + "@tryghost/kg-default-transforms" "1.2.28" jsdom "^24.1.1" lexical "0.13.1" -"@tryghost/kg-lexical-html-renderer@1.3.24": - version "1.3.24" - resolved "https://registry.yarnpkg.com/@tryghost/kg-lexical-html-renderer/-/kg-lexical-html-renderer-1.3.24.tgz#458b9adc66ac9d7853f25b93b258ffbba8412581" - integrity sha512-Cuc4TL9itKhzcpM8FwQdxwQZQeb4Xe164jfJyygmsrkRg7mAwv7iRWmiHVL656nNaIyNFp4nplJxkHEXnLW5FQ== +"@tryghost/kg-lexical-html-renderer@1.3.28": + version "1.3.28" + resolved "https://registry.yarnpkg.com/@tryghost/kg-lexical-html-renderer/-/kg-lexical-html-renderer-1.3.28.tgz#8397cae07b5975a25a43c39547b0f82f33fda149" + integrity sha512-CTLg7yAlhH114gcrk0ZuLXCAufE8Fi4cEy8iLt4m0UAD6x6irrEDc3/rVQR/8vS6EFzJG84iJ2BcqLOuZ1b46Q== dependencies: "@lexical/clipboard" "0.13.1" "@lexical/code" "0.13.1" @@ -9142,8 +9147,8 @@ "@lexical/link" "0.13.1" "@lexical/list" "0.13.1" "@lexical/rich-text" "0.13.1" - "@tryghost/kg-default-nodes" "2.0.1" - "@tryghost/kg-default-transforms" "1.2.24" + "@tryghost/kg-default-nodes" "2.0.5" + "@tryghost/kg-default-transforms" "1.2.28" jsdom "^24.1.1" lexical "0.13.1" @@ -9162,12 +9167,12 @@ markdown-it-sup "^2.0.0" semver "^7.7.0" -"@tryghost/kg-markdown-html-renderer@7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-7.1.3.tgz#f00370d0991cb519b62cd8d39421f1d5c5e19b63" - integrity sha512-1UzWqm9+UK2fxoI0mJwNzUSbUm/weqAo0b1jeFPyU3BRtO+lRYvEWv/X5KQRBqLq6HEih2Qe8H1roTPzUKzxfA== +"@tryghost/kg-markdown-html-renderer@7.1.7": + version "7.1.7" + resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-7.1.7.tgz#b063280bcf5f16c72cf702c173fdf2cf7b12bf6d" + integrity sha512-B6d1ins3CKpAvUAPGFa/LZVD8gHM/9XseKSy5utR3Jnii+iPbGYa4ljhQcXEy5Q27JxKhakTDvWMBOxYIiSTHw== dependencies: - "@tryghost/kg-utils" "1.0.32" + "@tryghost/kg-utils" "1.0.36" markdown-it "^14.0.0" markdown-it-footnote "^4.0.0" markdown-it-image-lazy-loading "^2.0.0" @@ -9177,41 +9182,26 @@ markdown-it-sup "^2.0.0" semver "^7.7.0" -"@tryghost/kg-markdown-html-renderer@7.1.6": - version "7.1.6" - resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-7.1.6.tgz#0fb51df1e58ac73c9541b2055259deace2c2cfac" - integrity sha512-hGpKlP42/FO8KscxDIdLBLCXZjvc83qm+pYtBy9oYshAp0ZmLDzCw7LVVZ2f7RW+6d8EXM+uWnOwHU10Z8fAGA== +"@tryghost/kg-mobiledoc-html-renderer@7.1.7": + version "7.1.7" + resolved "https://registry.yarnpkg.com/@tryghost/kg-mobiledoc-html-renderer/-/kg-mobiledoc-html-renderer-7.1.7.tgz#ca9a8faf7f9b50b9f72ab00e44614d09823ad1c4" + integrity sha512-M+gRzvUwiy4lelj1QDid08MXuuALpe0TAooBo4CweW+IdjG+Pd5jVLfEUW5mrHezy7AiMEa4/ednmoycoG4Iow== dependencies: - "@tryghost/kg-utils" "1.0.35" - markdown-it "^14.0.0" - markdown-it-footnote "^4.0.0" - markdown-it-image-lazy-loading "^2.0.0" - markdown-it-lazy-headers "^0.1.3" - markdown-it-mark "^4.0.0" - markdown-it-sub "^2.0.0" - markdown-it-sup "^2.0.0" - semver "^7.7.0" - -"@tryghost/kg-mobiledoc-html-renderer@7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@tryghost/kg-mobiledoc-html-renderer/-/kg-mobiledoc-html-renderer-7.1.3.tgz#297c9a1a04125994d373cf551c5fd9d6d10e5959" - integrity sha512-tHHtPRxkVuRyvON3dNYDTMeSmZ//TABuit2O3i9khlLlVMFSECEc+y3F8jUwhAZpCMlTKLLGQxAkF2Mg2r4lOw== - dependencies: - "@tryghost/kg-utils" "1.0.32" + "@tryghost/kg-utils" "1.0.36" mobiledoc-dom-renderer "^0.7.0" simple-dom "^1.4.0" -"@tryghost/kg-parser-plugins@4.2.7": - version "4.2.7" - resolved "https://registry.yarnpkg.com/@tryghost/kg-parser-plugins/-/kg-parser-plugins-4.2.7.tgz#75f0a7450ed0be5010110cdfbd80560fe26cf61c" - integrity sha512-dIwnVei8CETWsPhMO3uzB/rjje5fj8csu3FvOr9c7/2KSlYomN3da68t66pILCWcHL3oH3LW80zNxoMo02nVyA== +"@tryghost/kg-parser-plugins@4.2.11": + version "4.2.11" + resolved "https://registry.yarnpkg.com/@tryghost/kg-parser-plugins/-/kg-parser-plugins-4.2.11.tgz#5d47ef60939400a9e226cc4a64446d016dd49156" + integrity sha512-Kf3nwbw3SzwYVBjilF+nLkSSeVNU41Bqr1L1A+MdFXScN14wx6grjZ79Bn0hpKKvADmXD/m7McYv/3KF5c6gZQ== dependencies: - "@tryghost/kg-clean-basic-html" "4.2.7" + "@tryghost/kg-clean-basic-html" "4.2.11" -"@tryghost/kg-unsplash-selector@0.3.6": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@tryghost/kg-unsplash-selector/-/kg-unsplash-selector-0.3.6.tgz#7b573600efce885e3a7ba8382dfff16c409e3c49" - integrity sha512-tjCa9ynS2ODtCCFsOetKMS5Ov3BqvtgVJHdBqLlk7cJBt1ZBJDI7IDuKcqkwOhDm15SHQHbG1lNPHGG2wRCGGg== +"@tryghost/kg-unsplash-selector@0.3.10": + version "0.3.10" + resolved "https://registry.yarnpkg.com/@tryghost/kg-unsplash-selector/-/kg-unsplash-selector-0.3.10.tgz#522bed7056a7261100039f2e571fc2019f0efdb6" + integrity sha512-3EYHSuEPHbKEu4Zb6+dwietHqIN2f2Zu55YXyvqHFvAVNVQxzSMh94YjiL2837+Q0U/n3cFKtxRZ2CNMo0ehxg== "@tryghost/kg-utils@1.0.31": version "1.0.31" @@ -9220,24 +9210,17 @@ dependencies: semver "^7.7.0" -"@tryghost/kg-utils@1.0.32": - version "1.0.32" - resolved "https://registry.yarnpkg.com/@tryghost/kg-utils/-/kg-utils-1.0.32.tgz#e121b90fd42bd1730c0c32e36171ab619b6e331b" - integrity sha512-fS25Qm4mORKhfXi267Qb+Oyn55vMLT+U05uPB1ql3OQurzBfm6oA3iJAFeSpfrbmV8MtyQ/DOOWRvZamb3DCRg== - dependencies: - semver "^7.7.0" - -"@tryghost/kg-utils@1.0.35": - version "1.0.35" - resolved "https://registry.yarnpkg.com/@tryghost/kg-utils/-/kg-utils-1.0.35.tgz#d7232b446d624936096a14deffe52681ba1586e7" - integrity sha512-JPQYHEeuQh0pajiWDubVF2172DuxSjZSK2AcYpZMsDYG27lm70VAecBpwQdotsT/5LF0CvWVSqqzAjH0RsZ3Rg== +"@tryghost/kg-utils@1.0.36": + version "1.0.36" + resolved "https://registry.yarnpkg.com/@tryghost/kg-utils/-/kg-utils-1.0.36.tgz#2820a87dea4d6ca31fa5c30d3bd384f89b501719" + integrity sha512-TcasreXfzDCDC6bibfZAy4nOFsreCNzEKpjvQN/3UcKfT1OiFdjsvlw+8AxzZoYU5osYakpRVu3Xqwu1qOFU8w== dependencies: semver "^7.7.0" -"@tryghost/koenig-lexical@1.7.2": - version "1.7.2" - resolved "https://registry.yarnpkg.com/@tryghost/koenig-lexical/-/koenig-lexical-1.7.2.tgz#03de94b698b1071f17a1a8a053fe060ed9c4f785" - integrity sha512-GqE03JX6277X9slx1WoXblw1Sd2mGW1zWhvKpifGbs/ePR4oaBtpaq3OpNmMvWqfAaE3hXnHxYPy8J9gs/HnvQ== +"@tryghost/koenig-lexical@1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@tryghost/koenig-lexical/-/koenig-lexical-1.7.6.tgz#f275859e08bc44624f377ea9cddde2d71c46fc8c" + integrity sha512-4UXck0y+L/GuoxOxBJTvpCZvRA/r4nixJ/g2oFWr5gXtocmTpLbYEZDpUQ6H8eRAgC8Ocdthiyr9b8sXhqQpdw== "@tryghost/limit-service@1.4.1": version "1.4.1"