gatsby-source-ghost
Advanced tools
Comparing version 4.0.6 to 4.2.0
@@ -0,10 +1,39 @@ | ||
/**** | ||
* gatsby-node.js | ||
* | ||
* Generate Gatsby nodes based on a custom schema derived from the Ghost V3 API spec. | ||
* | ||
* This source plugin will source and generate Posts, Pages, Tags, Authors and Settings. | ||
* | ||
* https://ghost.org/docs/api/v3/ | ||
*/ | ||
const Promise = require('bluebird'); | ||
const ContentAPI = require('./content-api'); | ||
const {PostNode, PageNode, TagNode, AuthorNode, SettingsNode, fakeNodes} = require('./ghost-nodes'); | ||
const { | ||
PostNode, | ||
PageNode, | ||
TagNode, | ||
AuthorNode, | ||
SettingsNode | ||
} = require('./ghost-nodes'); | ||
const _ = require(`lodash`); | ||
const cheerio = require(`cheerio`); | ||
/** | ||
* Import all custom ghost types. | ||
*/ | ||
const ghostTypes = require('./ghost-schema'); | ||
/** | ||
* Extract specific tags from html and return them in a new object. | ||
* | ||
* Only style tags are extracted at present. | ||
*/ | ||
const parseCodeinjection = (html) => { | ||
let $ = null; | ||
/** | ||
* Attempt to load the HTML into cheerio. Do not escape the HTML. | ||
*/ | ||
try { | ||
@@ -16,5 +45,11 @@ $ = cheerio.load(html, {decodeEntities: false}); | ||
/** | ||
* Extract all style tags from the markup. | ||
*/ | ||
const $parsedStyles = $(`style`); | ||
const codeInjObj = {}; | ||
/** | ||
* For each extracted tag, add or append the tag's HTML to the new object. | ||
*/ | ||
$parsedStyles.each((i, style) => { | ||
@@ -31,5 +66,14 @@ if (i === 0) { | ||
/** | ||
* Extracts specific tags from the code injection header and footer and | ||
* transforms posts to include extracted tags as a new key and value in the post object. | ||
* | ||
* Only the `codeinjection_styles` key is added at present. | ||
*/ | ||
const transformCodeinjection = (posts) => { | ||
posts.map((post) => { | ||
const allCodeinjections = [post.codeinjection_head, post.codeinjection_foot].join(''); | ||
const allCodeinjections = [ | ||
post.codeinjection_head, | ||
post.codeinjection_foot | ||
].join(''); | ||
@@ -48,4 +92,2 @@ if (!allCodeinjections) { | ||
post.codeinjection_styles = _.isNil(post.codeinjection_styles) ? '' : post.codeinjection_styles; | ||
return post; | ||
@@ -62,3 +104,3 @@ }); | ||
*/ | ||
const createLiveGhostNodes = ({actions}, configOptions) => { | ||
exports.sourceNodes = ({actions}, configOptions) => { | ||
const {createNode} = actions; | ||
@@ -68,2 +110,8 @@ | ||
const ignoreNotFoundElseRethrow = (err) => { | ||
if (err.response.status !== 404) { | ||
throw err; | ||
} | ||
}; | ||
const postAndPageFetchOptions = { | ||
@@ -75,10 +123,14 @@ limit: 'all', | ||
const fetchPosts = api.posts.browse(postAndPageFetchOptions).then((posts) => { | ||
posts = transformCodeinjection(posts); | ||
posts.forEach(post => createNode(PostNode(post))); | ||
}); | ||
const fetchPosts = api.posts | ||
.browse(postAndPageFetchOptions) | ||
.then((posts) => { | ||
posts = transformCodeinjection(posts); | ||
posts.forEach(post => createNode(PostNode(post))); | ||
}).catch(ignoreNotFoundElseRethrow); | ||
const fetchPages = api.pages.browse(postAndPageFetchOptions).then((pages) => { | ||
pages.forEach(page => createNode(PageNode(page))); | ||
}); | ||
const fetchPages = api.pages | ||
.browse(postAndPageFetchOptions) | ||
.then((pages) => { | ||
pages.forEach(page => createNode(PageNode(page))); | ||
}).catch(ignoreNotFoundElseRethrow); | ||
@@ -90,22 +142,38 @@ const tagAndAuthorFetchOptions = { | ||
const fetchTags = api.tags.browse(tagAndAuthorFetchOptions).then((tags) => { | ||
tags.forEach((tag) => { | ||
tag.postCount = tag.count.posts; | ||
createNode(TagNode(tag)); | ||
}); | ||
}); | ||
const fetchTags = api.tags | ||
.browse(tagAndAuthorFetchOptions) | ||
.then((tags) => { | ||
tags.forEach((tag) => { | ||
tag.postCount = tag.count.posts; | ||
createNode(TagNode(tag)); | ||
}); | ||
}).catch(ignoreNotFoundElseRethrow); | ||
const fetchAuthors = api.authors.browse(tagAndAuthorFetchOptions).then((authors) => { | ||
authors.forEach((author) => { | ||
author.postCount = author.count.posts; | ||
createNode(AuthorNode(author)); | ||
}); | ||
}); | ||
const fetchAuthors = api.authors | ||
.browse(tagAndAuthorFetchOptions) | ||
.then((authors) => { | ||
authors.forEach((author) => { | ||
author.postCount = author.count.posts; | ||
createNode(AuthorNode(author)); | ||
}); | ||
}).catch(ignoreNotFoundElseRethrow); | ||
const fetchSettings = api.settings.browse().then((setting) => { | ||
const codeinjectionHead = setting.codeinjection_head || setting.ghost_head; | ||
const codeinjectionFoot = setting.codeinjection_foot || setting.ghost_foot; | ||
const allCodeinjections = codeinjectionHead ? codeinjectionHead.concat(codeinjectionFoot) : | ||
codeinjectionFoot ? codeinjectionFoot : null; | ||
/** | ||
* Assert the presence of any code injections, from both the use and ghost. | ||
*/ | ||
const codeinjectionHead = | ||
setting.codeinjection_head || setting.ghost_head; | ||
const codeinjectionFoot = | ||
setting.codeinjection_foot || setting.ghost_foot; | ||
const allCodeinjections = codeinjectionHead | ||
? codeinjectionHead.concat(codeinjectionFoot) | ||
: codeinjectionFoot | ||
? codeinjectionFoot | ||
: null; | ||
/** | ||
* If there are any code injections, extract style tags from the markup and | ||
* transform the setting object to include the `codeinjection_styles` key with the value of those style tags. | ||
*/ | ||
if (allCodeinjections) { | ||
@@ -121,49 +189,32 @@ const parsedCodeinjections = parseCodeinjection(allCodeinjections); | ||
setting.codeinjection_styles = _.isNil(setting.codeinjection_styles) ? '' : setting.codeinjection_styles; | ||
/** | ||
* Ensure always non-null by setting `codeinjection_styles` to | ||
* an empty string instead of null. | ||
*/ | ||
setting.codeinjection_styles = _.isNil(setting.codeinjection_styles) | ||
? '' | ||
: setting.codeinjection_styles; | ||
// The settings object doesn't have an id, prevent Gatsby from getting 'undefined' | ||
setting.id = 1; | ||
createNode(SettingsNode(setting)); | ||
}); | ||
}).catch(ignoreNotFoundElseRethrow); | ||
return Promise.all([fetchPosts, fetchPages, fetchTags, fetchAuthors, fetchSettings]); | ||
return Promise.all([ | ||
fetchPosts, | ||
fetchPages, | ||
fetchTags, | ||
fetchAuthors, | ||
fetchSettings | ||
]); | ||
}; | ||
/** | ||
* Create Temporary Fake Nodes | ||
* Refs: https://github.com/gatsbyjs/gatsby/issues/10856#issuecomment-451701011 | ||
* Ensures that Gatsby knows about every field in the Ghost schema | ||
* Creates custom types based on the Ghost V3 API. | ||
* | ||
* This creates a fully custom schema, removing the need for dummy content or fake nodes. | ||
*/ | ||
const createTemporaryFakeNodes = ({emitter, actions}) => { | ||
// Setup our temporary fake nodes | ||
fakeNodes.forEach((node) => { | ||
// createTemporaryFakeNodes is called twice. The second time, the node already has an owner | ||
// This triggers an error, so we clean the node before trying again | ||
delete node.internal.owner; | ||
actions.createNode(node); | ||
}); | ||
const onSchemaUpdate = () => { | ||
// Destroy our temporary fake nodes | ||
fakeNodes.forEach((node) => { | ||
actions.deleteNode({node}); | ||
}); | ||
emitter.off(`SET_SCHEMA`, onSchemaUpdate); | ||
}; | ||
// Use a Gatsby internal API to cleanup our Fake Nodes | ||
emitter.on(`SET_SCHEMA`, onSchemaUpdate); | ||
exports.createSchemaCustomization = ({actions}) => { | ||
const {createTypes} = actions; | ||
createTypes(ghostTypes); | ||
}; | ||
// Standard way to create nodes | ||
exports.sourceNodes = ({emitter, actions}, configOptions) => { | ||
// These temporary nodes ensure that Gatsby knows about every field in the Ghost Schema | ||
createTemporaryFakeNodes({emitter, actions}); | ||
// Go and fetch live data, and populate the nodes | ||
return createLiveGhostNodes({actions}, configOptions); | ||
}; | ||
// Secondary point in build where we have to create fake Nodes | ||
exports.onPreExtractQueries = ({emitter, actions}) => { | ||
createTemporaryFakeNodes({emitter, actions}); | ||
}; |
const createNodeHelpers = require('gatsby-node-helpers').default; | ||
const schema = require('./ghost-schema'); | ||
const { | ||
createNodeFactory | ||
} = createNodeHelpers({ | ||
const {createNodeFactory} = createNodeHelpers({ | ||
typePrefix: 'Ghost' | ||
@@ -22,10 +19,2 @@ }); | ||
const fakeNodes = [ | ||
PostNode(schema.post), | ||
PageNode(schema.page), | ||
TagNode(schema.tag), | ||
AuthorNode(schema.author), | ||
SettingsNode(schema.settings) | ||
]; | ||
module.exports = { | ||
@@ -36,4 +25,3 @@ PostNode, | ||
AuthorNode, | ||
SettingsNode, | ||
fakeNodes | ||
SettingsNode | ||
}; |
@@ -1,158 +0,175 @@ | ||
const tag = { | ||
id: 'a6fd74f5667245d9b678429bc35febbf', | ||
name: 'Data schema primary', | ||
slug: 'data-schema', | ||
url: 'https://demo.ghost.io/tag/data-schema-tag/', | ||
description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
feature_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
visibility: 'public', | ||
meta_title: 'Data schema primary', | ||
meta_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
postCount: 1, | ||
og_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
og_title: 'Data schema primary', | ||
og_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
twitter_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
twitter_title: 'Data schema primary', | ||
twitter_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
codeinjection_head: null, | ||
codeinjection_foot: null, | ||
canonical_url: 'https://demo.ghost.io/tag/data-schema-tag/', | ||
accent_color: '#ffffff' | ||
}; | ||
const author = { | ||
id: '179e06da7ae846929bb30f19f3e82ecb', | ||
name: 'Data Schema Author', | ||
slug: 'data-schema-author', | ||
url: 'https://demo.ghost.io/author/data-schema-author/', | ||
profile_image: 'https://casper.ghost.org/v2.0.0/images/ghost.png', | ||
cover_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
bio: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
website: 'https://ghost.org', | ||
location: 'The Internet', | ||
facebook: 'ghost', | ||
twitter: '@ghost', | ||
meta_title: 'Data Schema Author', | ||
meta_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
postCount: 1 | ||
}; | ||
/** | ||
* Custom schema with types based on the Ghost V3 API spec. | ||
* | ||
* Note that GhostPost and GhostPage are identical. | ||
* | ||
* Foreign Keys are linked by 'slug'. | ||
* | ||
* `GhostNavigation` and `GhostPostCount` are custom types which do not become nodes. | ||
* They instead represent the shape of objects returned by the Ghost API for navigation and post count. | ||
*/ | ||
const navigation = [ | ||
{label: 'Home', url: '/'}, | ||
{label: 'Tag', url: '/tag/getting-started/'}, | ||
{label: 'Author', url: '/author/ghost/'}, | ||
{label: 'Help', url: 'https://help.ghost.org'} | ||
]; | ||
const types = ` | ||
type GhostPost implements Node { | ||
slug: String! | ||
id: ID! | ||
uuid: String! | ||
title: String! | ||
html: String! | ||
comment_id: String! | ||
feature_image: String | ||
featured: Boolean! | ||
visibility: String! | ||
created_at: Date! @dateformat | ||
updated_at: Date! @dateformat | ||
published_at: Date! @dateformat | ||
custom_excerpt: String | ||
codeinjection_head: String | ||
codeinjection_foot: String | ||
codeinjection_styles: String | ||
custom_template: String | ||
canonical_url: String | ||
send_email_when_published: Boolean | ||
tags: [GhostTag] @link(from: "tags.slug" by: "slug") | ||
authors: [GhostAuthor]! @link(from: "authors.slug" by: "slug") | ||
primary_author: GhostAuthor! @link(from: "primary_author.slug" by: "slug") | ||
primary_tag: GhostTag @link(from: "primary_tag.slug" by: "slug") | ||
url: String! | ||
excerpt: String! | ||
reading_time: Int! | ||
email_subject: String | ||
plaintext: String | ||
page: Boolean | ||
og_image: String | ||
og_title: String | ||
og_description: String | ||
twitter_image: String | ||
twitter_title: String | ||
twitter_description: String | ||
meta_title: String | ||
meta_description: String | ||
email_subject: String | ||
} | ||
const post = { | ||
id: '5bbafb3cb7ec4135e42fce56', | ||
uuid: '472cd89d-953c-42ad-ae18-974b35444d03', | ||
title: 'Data schema', | ||
slug: 'data-schema', | ||
url: 'https://demo.ghost.io/data-schema/', | ||
canonical_url: 'https://demo.ghost.io/data-schema-page/', | ||
mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function"]]]]}', | ||
html: '<p>This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function</p>', | ||
comment_id: '5bb75b5a37361dae192eff1b', | ||
plaintext: 'This is a data schema stub for Gatsby.js and is not used. It must exist for\nbuilds to function', | ||
feature_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
featured: true, | ||
page: false, | ||
meta_title: 'Data schema', | ||
meta_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
created_at: '2018-12-04T13:59:08.000+00:00', | ||
updated_at: '2018-12-04T13:59:08.000+00:00', | ||
published_at: '2018-12-04T13:59:14.000+00:00', | ||
custom_excerpt: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
excerpt: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
codeinjection_head: '<style>.some-class {\n}<style><script>function(){console.log("hello");}</script>', | ||
codeinjection_foot: '<style>.some-class {\n}<style><script>function(){console.log("hello");}</script>', | ||
codeinjection_styles: '.some-class {\n}', | ||
og_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
og_title: 'Data schema', | ||
og_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
twitter_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
twitter_title: 'Data schema', | ||
twitter_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
primary_author: author, | ||
primary_tag: tag, | ||
authors: [author], | ||
tags: [tag], | ||
visibility: 'public', | ||
reading_time: 1 | ||
}; | ||
const page = { | ||
id: '5bbafb3cb7ec4135e42fce57', | ||
uuid: '472cd89d-953c-42ad-ae18-974b35444d04', | ||
title: 'Data schema', | ||
slug: 'data-schema-page', | ||
url: 'https://demo.ghost.io/data-schema-page/', | ||
canonical_url: 'https://demo.ghost.io/data-schema-page/', | ||
mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function"]]]]}', | ||
html: '<p>This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function</p>', | ||
comment_id: '5bb75b5a37361dae192eff1b', | ||
plaintext: 'This is a data schema stub for Gatsby.js and is not used. It must exist for\nbuilds to function', | ||
feature_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
featured: false, | ||
page: true, | ||
meta_title: 'Data schema', | ||
meta_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
created_at: '2018-12-04T13:59:08.000+00:00', | ||
updated_at: '2018-12-04T13:59:08.000+00:00', | ||
published_at: '2018-12-04T13:59:14.000+00:00', | ||
custom_excerpt: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
excerpt: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
codeinjection_head: '<style>.some-class {\n}<style><script>function(){console.log("hello");}</script>', | ||
codeinjection_foot: '<style>.some-class {\n}<style><script>function(){console.log("hello");}</script>', | ||
codeinjection_styles: '.some-class {\n}', | ||
og_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
og_title: 'Data schema', | ||
og_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
twitter_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
twitter_title: 'Data schema', | ||
twitter_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
custom_template: 'post.hbs', | ||
primary_author: author, | ||
primary_tag: tag, | ||
authors: [author], | ||
tags: [tag], | ||
visibility: 'public', | ||
reading_time: 1 | ||
}; | ||
type GhostPage implements Node { | ||
slug: String! | ||
id: ID! | ||
uuid: String! | ||
title: String! | ||
html: String! | ||
comment_id: String! | ||
feature_image: String | ||
featured: Boolean! | ||
visibility: String! | ||
created_at: Date! @dateformat | ||
updated_at: Date! @dateformat | ||
published_at: Date! @dateformat | ||
custom_excerpt: String | ||
codeinjection_head: String | ||
codeinjection_foot: String | ||
codeinjection_styles: String | ||
custom_template: String | ||
canonical_url: String | ||
send_email_when_published: Boolean | ||
tags: [GhostTag] @link(from: "tags.slug" by: "slug") | ||
authors: [GhostAuthor]! @link(from: "authors.slug" by: "slug") | ||
primary_author: GhostAuthor! @link(from: "primary_author.slug" by: "slug") | ||
primary_tag: GhostTag @link(from: "primary_tag.slug" by: "slug") | ||
url: String! | ||
excerpt: String! | ||
reading_time: Int! | ||
email_subject: String | ||
plaintext: String | ||
page: Boolean | ||
og_image: String | ||
og_title: String | ||
og_description: String | ||
twitter_image: String | ||
twitter_title: String | ||
twitter_description: String | ||
meta_title: String | ||
meta_description: String | ||
email_subject: String | ||
} | ||
const settings = { | ||
title: 'Ghost', | ||
description: 'The professional publishing platform', | ||
logo: 'https://static.ghost.org/v1.0.0/images/ghost-logo.svg', | ||
icon: 'https://static.ghost.org/favicon.ico', | ||
cover_image: 'https://static.ghost.org/v1.0.0/images/blog-cover.jpg', | ||
facebook: 'ghost', | ||
twitter: '@ghost', | ||
lang: 'en', | ||
timezone: 'Etc/UTC', | ||
codeinjection_head: '<script>>some script</script><style></style>', | ||
codeinjection_foot: '<style>.some-class {\n}</style><script></script>', | ||
codeinjection_styles: '.some-class {\n}', | ||
navigation: navigation, | ||
secondary_navigation: navigation, | ||
meta_title: 'Data schema', | ||
meta_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
og_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
og_title: 'Data schema', | ||
og_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
twitter_image: 'https://images.unsplash.com/photo-1532630571098-79a3d222b00d?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=a88235003c40468403f936719134519d', | ||
twitter_title: 'Data schema', | ||
twitter_description: 'This is a data schema stub for Gatsby.js and is not used. It must exist for builds to function', | ||
members_support_address: 'noreply@demo.ghost.io', | ||
url: 'https://demo.ghost.io/', | ||
active_timezone: 'Etc/UTC', | ||
default_locale: 'en' | ||
}; | ||
type GhostTag implements Node { | ||
slug: String! | ||
id: ID! | ||
name: String! | ||
description: String | ||
feature_image: String | ||
visibility: String! | ||
meta_title: String | ||
meta_description: String | ||
url: String! | ||
count: GhostPostCount | ||
postCount: Int | ||
og_image: String | ||
og_title: String | ||
og_description: String | ||
twitter_image: String | ||
twitter_title: String | ||
twitter_description: String | ||
codeinjection_head: String | ||
codeinjection_foot: String | ||
canonical_url: String | ||
accent_color: String | ||
} | ||
module.exports = { | ||
post, | ||
page, | ||
tag, | ||
author, | ||
settings | ||
}; | ||
type GhostAuthor implements Node { | ||
slug: String! | ||
id: ID! | ||
name: 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! | ||
count: GhostPostCount! | ||
postCount: Int! | ||
} | ||
type GhostSettings implements Node { | ||
title: String | ||
description: String | ||
logo: String | ||
icon: String | ||
cover_image: String | ||
facebook: String | ||
twitter: String | ||
lang: String! | ||
timezone: String! | ||
navigation: [GhostNavigation] | ||
secondary_navigation: [GhostNavigation] | ||
meta_title: String | ||
meta_description: String | ||
og_image: String | ||
og_title: String | ||
og_description: String | ||
twitter_image: String | ||
twitter_title: String | ||
twitter_description: String | ||
url: String! | ||
codeinjection_head: String | ||
codeinjection_foot: String | ||
codeinjection_styles: String! | ||
active_timezone: String | ||
default_locale: String | ||
} | ||
type GhostNavigation { | ||
label: String! | ||
url: String! | ||
} | ||
type GhostPostCount { | ||
posts: Int | ||
} | ||
`; | ||
module.exports = types; |
{ | ||
"name": "gatsby-source-ghost", | ||
"version": "4.0.6", | ||
"version": "4.2.0", | ||
"description": "Gatsby source plugin for building websites using the Ghost API as a data source.", | ||
@@ -5,0 +5,0 @@ "repository": "git@github.com:TryGhost/gatsby-source-ghost.git", |
const testUtils = require('./utils'); | ||
const ContentAPI = require('../content-api'); | ||
const gatsbyNode = require('../gatsby-node'); | ||
const ghostSchema = require('../ghost-schema'); | ||
@@ -15,33 +14,20 @@ describe('Basic Functionality', function () { | ||
it('Gatsby Node is able to create fake and real nodes', function (done) { | ||
it('Gatsby Node is able to create real nodes', function (done) { | ||
const createNode = sinon.stub(); | ||
const deleteNode = sinon.stub(); | ||
const emitter = { | ||
on: sinon.stub().callsArg(1), | ||
off: sinon.stub() | ||
}; | ||
gatsbyNode | ||
.sourceNodes({actions: {createNode, deleteNode}, emitter}, {}) | ||
.sourceNodes({actions: {createNode}}, {}) | ||
.then(() => { | ||
createNode.callCount.should.eql(12); | ||
deleteNode.callCount.should.eql(5); | ||
createNode.callCount.should.eql(7); | ||
const getFirstArg = call => createNode.getCall(call).args[0]; | ||
// Check Fake Nodes against schema | ||
getFirstArg(0).should.be.a.ValidGatsbyNode('GhostPost', ghostSchema.post); | ||
getFirstArg(1).should.be.a.ValidGatsbyNode('GhostPage', ghostSchema.page); | ||
getFirstArg(2).should.be.a.ValidGatsbyNode('GhostTag', ghostSchema.tag); | ||
getFirstArg(3).should.be.a.ValidGatsbyNode('GhostAuthor', ghostSchema.author); | ||
getFirstArg(4).should.be.a.ValidGatsbyNode('GhostSettings', ghostSchema.settings); | ||
// Check Real Nodes are created | ||
getFirstArg(5).should.be.a.ValidGatsbyNode('GhostPost'); | ||
getFirstArg(6).should.be.a.ValidGatsbyNode('GhostPage'); | ||
getFirstArg(7).should.be.a.ValidGatsbyNode('GhostTag'); | ||
getFirstArg(8).should.be.a.ValidGatsbyNode('GhostTag'); | ||
getFirstArg(9).should.be.a.ValidGatsbyNode('GhostAuthor'); | ||
getFirstArg(10).should.be.a.ValidGatsbyNode('GhostAuthor'); | ||
getFirstArg(11).should.be.a.ValidGatsbyNode('GhostSettings'); | ||
getFirstArg(0).should.be.a.ValidGatsbyNode('GhostPost'); | ||
getFirstArg(1).should.be.a.ValidGatsbyNode('GhostPage'); | ||
getFirstArg(2).should.be.a.ValidGatsbyNode('GhostTag'); | ||
getFirstArg(3).should.be.a.ValidGatsbyNode('GhostTag'); | ||
getFirstArg(4).should.be.a.ValidGatsbyNode('GhostAuthor'); | ||
getFirstArg(5).should.be.a.ValidGatsbyNode('GhostAuthor'); | ||
getFirstArg(6).should.be.a.ValidGatsbyNode('GhostSettings'); | ||
@@ -48,0 +34,0 @@ done(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21
520
24004
1