Implemented pages.hide_title_and_feature_image property in API (#17211)

closes https://github.com/TryGhost/Product/issues/3557

- bumped `@tryghost/admin-api-schema` to allow passthrough of the new property in API requests
- updated output mapper to ensure property always returns a boolean rather than `null` in the case where `posts_meta` doesn't exist for a page
- updated `PostsService.copyPost()` to include the new property when copying
- updated `checkResponse` test util and snapshots to expect `hide_title_and_feature_image` property in page API responses
- fixed pages e2e test so it doesn't inadvertently modify the match object breaking later tests
This commit is contained in:
Kevin Ansfield 2023-07-05 16:01:24 +02:00 committed by GitHub
parent 2a340bcab9
commit 5d8ea79788
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 199 additions and 39 deletions

View File

@ -8,8 +8,5 @@ module.exports = async (model, frame, options) => {
delete jsonModel.email_only;
delete jsonModel.newsletter_id;
// TODO: remove this once full API support is in place
delete jsonModel.hide_title_and_feature_image;
return jsonModel;
};

View File

@ -29,7 +29,7 @@ module.exports = async (model, frame, options = {}) => {
if (typeof model.toJSON === 'function') {
jsonModel = model.toJSON(frame.options);
} else {
// This is to satisy the interface which extraAttrs needs
// This is to satisfy the interface which extraAttrs needs
model = {
id: jsonModel.id,
get(attr) {
@ -105,7 +105,7 @@ module.exports = async (model, frame, options = {}) => {
// NOTE: the default of `email_only` is `false` which is why we default to `false` instead of `null`
// The undefined value is possible because `posts_meta` table is lazily created only one of the
// values is assigned.
const defaultValue = (attr === 'email_only') ? false : null;
const defaultValue = (attr === 'email_only' || attr === 'hide_title_and_feature_image') ? false : null;
jsonModel[attr] = _.get(jsonModel.posts_meta, attr) || defaultValue;
});
delete jsonModel.posts_meta;

View File

@ -66,7 +66,7 @@
"@tryghost/adapter-base-cache": "0.1.5",
"@tryghost/adapter-cache-redis": "0.0.0",
"@tryghost/adapter-manager": "0.0.0",
"@tryghost/admin-api-schema": "4.4.0",
"@tryghost/admin-api-schema": "4.5.0",
"@tryghost/announcement-bar-settings": "0.0.0",
"@tryghost/api-framework": "0.0.0",
"@tryghost/api-version-compatibility-service": "0.0.0",

View File

@ -24,6 +24,99 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": Any<Boolean>,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"lexical": null,
"meta_description": null,
"meta_title": null,
"mobiledoc": "{\\"version\\":\\"0.3.1\\",\\"ghostVersion\\":\\"4.0\\",\\"markups\\":[],\\"atoms\\":[],\\"cards\\":[],\\"sections\\":[[1,\\"p\\",[[0,[],0,\\"\\"]]]]}",
"og_description": null,
"og_image": null,
"og_title": null,
"post_revisions": Any<Array>,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"slug": "test-page-2",
"status": "published",
"tags": Any<Array>,
"tiers": Array [
Object {
"active": true,
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"currency": null,
"description": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"monthly_price": null,
"monthly_price_id": null,
"name": "Free",
"slug": "free",
"trial_days": 0,
"type": "free",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"visibility": "public",
"welcome_page_url": null,
"yearly_price": null,
"yearly_price_id": null,
},
Object {
"active": true,
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"currency": "usd",
"description": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"monthly_price": 500,
"monthly_price_id": null,
"name": "Default Product",
"slug": "default-product",
"trial_days": 0,
"type": "paid",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"visibility": "public",
"welcome_page_url": null,
"yearly_price": 5000,
"yearly_price_id": null,
},
],
"title": "Test Page",
"twitter_description": null,
"twitter_image": null,
"twitter_title": null,
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"url": Any<String>,
"uuid": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/,
"visibility": "public",
},
],
}
`;
exports[`Pages API Copy Can copy a page 2: [body] 1`] = `
Object {
"pages": Array [
Object {
"authors": Any<Array>,
"canonical_url": null,
"codeinjection_foot": null,
"codeinjection_head": null,
"comment_id": Any<String>,
"count": Object {
"negative_feedback": 0,
"paid_conversions": 0,
"positive_feedback": 0,
"signups": 0,
},
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
"custom_excerpt": null,
"custom_template": null,
"excerpt": null,
"feature_image": null,
"feature_image_alt": null,
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": Any<Boolean>,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"lexical": null,
"meta_description": null,
@ -90,7 +183,21 @@ Object {
}
`;
exports[`Pages API Copy Can copy a page 2: [body] 1`] = `
exports[`Pages API Copy Can copy a page 3: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "3668",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/pages\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
"vary": "Accept-Version, Origin, Accept-Encoding",
"x-powered-by": "Express",
}
`;
exports[`Pages API Update Can modify hide_title_and_feature_image property 1: [body] 1`] = `
Object {
"pages": Array [
Object {
@ -114,6 +221,8 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": true,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"lexical": null,
"meta_description": null,
@ -122,11 +231,11 @@ Object {
"og_description": null,
"og_image": null,
"og_title": null,
"post_revisions": Array [],
"post_revisions": Any<Array>,
"primary_author": Any<Object>,
"primary_tag": Any<Object>,
"published_at": null,
"slug": "test-page-copy-2",
"slug": "test-page",
"status": "draft",
"tags": Any<Array>,
"tiers": Array [
@ -167,7 +276,7 @@ Object {
"yearly_price_id": null,
},
],
"title": "Test Page (Copy)",
"title": "Test Page",
"twitter_description": null,
"twitter_image": null,
"twitter_title": null,
@ -180,30 +289,16 @@ Object {
}
`;
exports[`Pages API Copy Can copy a page 2: [headers] 1`] = `
exports[`Pages API Update Can modify hide_title_and_feature_image property 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "3631",
"content-length": "3667",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/pages\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
"vary": "Accept-Version, Origin, Accept-Encoding",
"x-powered-by": "Express",
}
`;
exports[`Pages API Copy Can copy a page 3: [headers] 1`] = `
Object {
"access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "3633",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/pages\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
"vary": "Accept-Version, Origin, Accept-Encoding",
"x-cache-invalidate": "/p/80038ac3-4ec7-4f4b-8b30-9aacf306ee1e/",
"x-powered-by": "Express",
}
`;

View File

@ -1,5 +1,5 @@
const {agentProvider, fixtureManager, mockManager, matchers} = require('../../utils/e2e-framework');
const {anyArray, anyContentVersion, anyEtag, anyLocationFor, anyObject, anyObjectId, anyISODateTime, anyString, anyUuid} = matchers;
const {anyArray, anyBoolean, anyContentVersion, anyEtag, anyLocationFor, anyObject, anyObjectId, anyISODateTime, anyString, anyUuid} = matchers;
const tierSnapshot = {
id: anyObjectId,
@ -20,7 +20,8 @@ const matchPageShallowIncludes = {
created_at: anyISODateTime,
updated_at: anyISODateTime,
published_at: anyISODateTime,
post_revisions: anyArray
post_revisions: anyArray,
hide_title_and_feature_image: anyBoolean
};
describe('Pages API', function () {
@ -36,6 +37,47 @@ describe('Pages API', function () {
mockManager.restore();
});
describe('Update', function () {
it('Can modify hide_title_and_feature_image property', async function () {
const page = {
title: 'Test Page',
status: 'draft'
};
const {body: pageBody} = await agent
.post('/pages/?formats=mobiledoc,lexical,html', {
headers: {
'content-type': 'application/json'
}
})
.body({pages: [page]})
.expectStatus(201);
const [pageResponse] = pageBody.pages;
await agent
.put(`/pages/${pageResponse.id}/?formats=mobiledoc,lexical,html`)
.body({
pages: [{
id: pageResponse.id,
hide_title_and_feature_image: true,
updated_at: pageResponse.updated_at // satisfy collision detection
}]
})
.expectStatus(200)
.matchBodySnapshot({
pages: [Object.assign({}, matchPageShallowIncludes, {
published_at: null,
hide_title_and_feature_image: true
})]
})
.matchHeaderSnapshot({
'content-version': anyContentVersion,
etag: anyEtag
});
});
});
describe('Copy', function () {
it('Can copy a page', async function () {
const page = {
@ -50,7 +92,10 @@ describe('Pages API', function () {
}
})
.body({pages: [page]})
.expectStatus(201);
.expectStatus(201)
.matchBodySnapshot({
pages: [Object.assign({}, matchPageShallowIncludes)]
});
const [pageResponse] = pageBody.pages;
@ -58,7 +103,7 @@ describe('Pages API', function () {
.post(`/pages/${pageResponse.id}/copy?formats=mobiledoc,lexical`)
.expectStatus(201)
.matchBodySnapshot({
pages: [Object.assign(matchPageShallowIncludes, {published_at: null})]
pages: [Object.assign({}, matchPageShallowIncludes, {published_at: null})]
})
.matchHeaderSnapshot({
'content-version': anyContentVersion,

View File

@ -131,7 +131,8 @@ const expectedProperties = {
'frontmatter',
'tiers',
'count',
'post_revisions'
'post_revisions',
'hide_title_and_feature_image'
],
user: _(schema.users)

View File

@ -21,6 +21,7 @@ Hopefully you don't find it a bore.",
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": "<!--kg-card-begin: markdown--><h1>Static page test is what this is for.</h1><p>Hopefully you don't find it a bore.</p><!--kg-card-end: markdown-->",
"id": "618ba1ffbe2896088840a6e9",
"meta_description": null,
@ -48,7 +49,7 @@ exports[`Pages Content API Can request page 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "*",
"cache-control": "public, max-age=0",
"content-length": "1083",
"content-length": "1120",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -90,6 +91,7 @@ Tip: If you're reading any post or page on your site and you notice something yo
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": "<p>Unlike posts, pages in Ghost don't appear in the main feed. They're separate, individual pages which only show up when you link to them. Great for content which is important, but separate from your usual posts.</p><p>An about page is a great example of one you might want to set up early on so people can find out more about you, and what you do. Why should people subscribe to your site and become a member? Details help!</p><blockquote><strong>Tip: </strong>If you're reading any post or page on your site and you notice something you want to edit, you can add <code>/edit</code> to the end of the URL and you'll be taken directly to the Ghost editor.</blockquote><p>Now tell the world what your site is all about.</p>",
"id": "6194d3ce51e2700162531a78",
"meta_description": null,
@ -134,6 +136,7 @@ If you prefer to use a contact form, almost all of the great embedded form servi
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": "<p>If you want to set up a contact page for people to be able to reach out to you, the simplest way is to set up a simple page like this and list the different ways people can reach out to you.</p><h3 id=\\"for-example-heres-how-to-reach-us\\">For example, here's how to reach us!</h3><ul><li><a href=\\"https://twitter.com/ghost?ref=127.0.0.1\\">@Ghost</a> on Twitter</li><li><a href=\\"https://www.facebook.com/ghost\\">@Ghost</a> on Facebook</li><li><a href=\\"https://instagram.com/ghost?ref=127.0.0.1\\">@Ghost</a> on Instagram</li></ul><p>If you prefer to use a contact form, almost all of the great embedded form services work great with Ghost and are easy to set up:</p><figure class=\\"kg-card kg-image-card\\"><a href=\\"https://ghost.org/integrations/?tag=forms&ref=127.0.0.1\\"><img src=\\"https://static.ghost.org/v4.0.0/images/integrations.png\\" class=\\"kg-image\\" alt loading=\\"lazy\\" width=\\"2944\\" height=\\"1716\\"></a></figure>",
"id": "6194d3ce51e2700162531a79",
"meta_description": null,
@ -174,6 +177,7 @@ Ghost is a non-profit organization, and we give away all our intellectual proper
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": "<p>Oh hey, you clicked every link of our starter content and even clicked this small link in the footer! If you like Ghost and you're enjoying the product so far, we'd hugely appreciate your support in any way you care to show it.</p><p>Ghost is a non-profit organization, and we give away all our intellectual property as open source software. If you believe in what we do, there are a number of ways you can give us a hand, and we hugely appreciate all of them:</p><ul><li>Contribute code via <a href=\\"https://github.com/tryghost?ref=127.0.0.1\\">GitHub</a></li><li>Contribute financially via <a href=\\"https://github.com/sponsors/TryGhost?ref=127.0.0.1\\">GitHub Sponsors</a></li><li>Contribute financially via <a href=\\"https://opencollective.com/ghost?ref=127.0.0.1\\">Open Collective</a></li><li>Contribute reviews via <strong>writing a blog post</strong></li><li>Contribute good vibes via <strong>telling your friends</strong> about us</li></ul><p>Thanks for checking us out!</p>",
"id": "6194d3ce51e2700162531a7b",
"meta_description": null,
@ -211,6 +215,7 @@ You can integrate any products, services, ads or integrations with Ghost yoursel
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": "<p>Wondering how Ghost fares when it comes to privacy and GDPR rules? Good news: Ghost does not use any tracking cookies of any kind.</p><p>You can integrate any products, services, ads or integrations with Ghost yourself if you want to, but it's always a good idea to disclose how subscriber data will be used by putting together a privacy page.</p>",
"id": "6194d3ce51e2700162531a7a",
"meta_description": null,
@ -248,6 +253,7 @@ Hopefully you don't find it a bore.",
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": "<!--kg-card-begin: markdown--><h1>Static page test is what this is for.</h1><p>Hopefully you don't find it a bore.</p><!--kg-card-end: markdown-->",
"id": "618ba1ffbe2896088840a6e9",
"meta_description": null,
@ -275,7 +281,7 @@ exports[`Pages Content API Can request pages 2: [headers] 1`] = `
Object {
"access-control-allow-origin": "*",
"cache-control": "public, max-age=0",
"content-length": "9233",
"content-length": "9418",
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -317,6 +323,7 @@ Tip: If you're reading any post or page on your site and you notice something yo
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"id": "6194d3ce51e2700162531a78",
"meta_description": null,
"meta_title": null,
@ -360,6 +367,7 @@ If you prefer to use a contact form, almost all of the great embedded form servi
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"id": "6194d3ce51e2700162531a79",
"meta_description": null,
"meta_title": null,
@ -399,6 +407,7 @@ Ghost is a non-profit organization, and we give away all our intellectual proper
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"id": "6194d3ce51e2700162531a7b",
"meta_description": null,
"meta_title": null,
@ -435,6 +444,7 @@ You can integrate any products, services, ads or integrations with Ghost yoursel
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"id": "6194d3ce51e2700162531a7a",
"meta_description": null,
"meta_title": null,
@ -471,6 +481,7 @@ Hopefully you don't find it a bore.",
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"id": "618ba1ffbe2896088840a6e9",
"meta_description": null,
"meta_title": null,

View File

@ -57,6 +57,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -300,6 +301,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -517,6 +519,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -734,6 +737,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -950,6 +954,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -1166,6 +1171,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -1383,6 +1389,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -1644,6 +1651,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -1845,6 +1853,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,
@ -2061,6 +2070,7 @@ Object {
"feature_image_caption": null,
"featured": false,
"frontmatter": null,
"hide_title_and_feature_image": false,
"html": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"meta_description": null,

View File

@ -556,7 +556,8 @@ class PostsService {
'meta_description',
'frontmatter',
'feature_image_alt',
'feature_image_caption'
'feature_image_caption',
'hide_title_and_feature_image'
]
);
}

View File

@ -6772,10 +6772,10 @@
resolved "https://registry.yarnpkg.com/@tryghost/adapter-base-cache/-/adapter-base-cache-0.1.5.tgz#66021c4e3e92bc623c82728ab50ca497ac41f7ae"
integrity sha512-ZAG7Qzn0RioU6yde67T9cneRtoD1ZxGcjwH81DdbL8ZqiPi66bmPw5TVOiEiFnny2XSDsPuUgc4/PxFO/RfV0g==
"@tryghost/admin-api-schema@4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@tryghost/admin-api-schema/-/admin-api-schema-4.4.0.tgz#aa33e7070c3195877df3a9e1284bed03f76ce7a8"
integrity sha512-so4LxkBYMqXqiFd/kJFNwOZ17Drx7uheeJTeUAcje7ZsLFqTYSOpLvpFr+OFnEhA00NiwgJxLyZbpm43kz60Nw==
"@tryghost/admin-api-schema@4.5.0":
version "4.5.0"
resolved "https://registry.yarnpkg.com/@tryghost/admin-api-schema/-/admin-api-schema-4.5.0.tgz#d4ac7122a3ae1d6468ee1cbfbd234f5474c28d8c"
integrity sha512-Bt+uQsDWUr/uk+E3ifZ7UmcgxJTVgwk+qHetYX1UF+dXGzrVFvflsfpatjJYBMORZ/rqtLvMm8HjPbnA3Fbkzg==
dependencies:
"@tryghost/errors" "^1.0.0"
ajv "^6.12.6"