-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Source related resource content from Swiftype #594
Merged
+6,533
−3
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
1329519
chore: install node-fetch
jerelmiller 0568e5c
feat: add local plugin that creates the json file that will be writte…
jerelmiller 10b2f78
chore: create the file empty for now
jerelmiller da64b13
feat: add ability to filter which pages are fetched
jerelmiller bb5c574
chore: write empty object to the data file by default
jerelmiller 27c6fe9
chore: use file option instead of path
jerelmiller 27c1481
feat: add general params that will be used to fetch from swiftype
jerelmiller 7a13ad7
chore: rename getPath to getParams that will be used to populate swif…
jerelmiller 9e3b486
feat: add tags to search query and write data to file in plugin
jerelmiller 8052577
refactor: move url helpers to utils file
jerelmiller 65b83c6
refactor: move path back to getPath function
jerelmiller 8232332
feat: fetch results from swiftype for the node and save the data
jerelmiller 7a4c0e5
fix: filter out certain document types to match the in product experi…
jerelmiller 6d77c70
feat: add config to enable swiftype builds using env variable
jerelmiller 6d7f1f4
chore: default getParams function
jerelmiller a90318d
refactor: move search logic out to own search function
jerelmiller 04b1828
refactor: use plain url strings intead of URL instance
jerelmiller 674e1c7
feat: filter out redirects and already defined urls for a page
jerelmiller 3f56794
chore: read/write to the json file in onCreateNode
jerelmiller 53053ef
chore: mock related pages by using json param data for now
jerelmiller d36afbc
feat: add graphql schema item and dummy resolver for related resources
jerelmiller 6685062
chore: better mock data
jerelmiller 753cd77
fix: fix race condition causing incorrect data to be written to file
jerelmiller 5c8cc98
refactor: slightly more efficient means of getting related resources …
jerelmiller f4c8fd1
feat: implement resolver for related resources
jerelmiller 3efef9d
feat: add actual related resource data
jerelmiller 0ad50b9
feat: properly resolve related resources for a node by linking the pa…
jerelmiller 689b3d5
chore: use getNodesByIds instead of getAllNodes
jerelmiller 89abf63
chore: exclude discuss and blog results
jerelmiller 489d004
chore: rename enabled to refetch
jerelmiller cc22434
feat: add limit argument to relatedResources
jerelmiller fd536e6
chore: rename pageLimit to limit
jerelmiller 4ce7c43
style: use arrow function instead
jerelmiller File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
const fs = require('fs'); | ||
const createRelatedResourceNode = require('./src/createRelatedResourceNode'); | ||
const getRelatedResources = require('./src/getRelatedResources'); | ||
|
||
const writeableData = {}; | ||
|
||
exports.onPreBootstrap = (_, pluginOptions) => { | ||
const { file } = pluginOptions; | ||
|
||
if (!fs.existsSync(file)) { | ||
fs.writeFileSync(file, '{}'); | ||
} | ||
}; | ||
|
||
exports.onCreateNode = async ( | ||
{ actions, node, getNodesByType, createNodeId, createContentDigest }, | ||
pluginOptions | ||
) => { | ||
const { createNode, createParentChildLink } = actions; | ||
const { filterNode = () => false, getPath } = pluginOptions; | ||
|
||
if (node.internal.type !== 'Mdx' || !filterNode({ node })) { | ||
return; | ||
} | ||
|
||
const [ | ||
{ | ||
siteMetadata: { siteUrl }, | ||
}, | ||
] = getNodesByType('Site'); | ||
|
||
const pathname = getPath({ node }); | ||
const resources = await getRelatedResources({ node, siteUrl }, pluginOptions); | ||
|
||
writeableData[pathname] = resources; | ||
|
||
resources.forEach((resource) => { | ||
const child = createRelatedResourceNode({ | ||
parent: node.id, | ||
resource, | ||
createContentDigest, | ||
createNode, | ||
createNodeId, | ||
}); | ||
|
||
createParentChildLink({ parent: node, child: child }); | ||
}); | ||
}; | ||
|
||
exports.createSchemaCustomization = ({ actions }) => { | ||
const { createTypes } = actions; | ||
|
||
const typeDefs = ` | ||
type RelatedResource implements Node { | ||
id: ID! | ||
title: String! | ||
url: String! | ||
} | ||
`; | ||
|
||
createTypes(typeDefs); | ||
}; | ||
|
||
exports.createResolvers = ({ createResolvers }) => { | ||
createResolvers({ | ||
Mdx: { | ||
relatedResources: { | ||
args: { | ||
limit: { | ||
type: 'Int', | ||
defaultValue: 5, | ||
}, | ||
}, | ||
type: ['RelatedResource!'], | ||
resolve: (source, args, context) => { | ||
const { limit } = args; | ||
|
||
return context.nodeModel | ||
.getNodesByIds({ ids: source.children }) | ||
.slice(0, Math.max(limit, 0)); | ||
}, | ||
}, | ||
}, | ||
}); | ||
}; | ||
|
||
exports.onPostBootstrap = (_, pluginOptions) => { | ||
const { refetch, file } = pluginOptions; | ||
|
||
if (refetch) { | ||
fs.writeFileSync(file, JSON.stringify(writeableData, null, 2)); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
25 changes: 25 additions & 0 deletions
25
plugins/gatsby-source-swiftype/src/createRelatedResourceNode.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module.exports = ({ | ||
createNode, | ||
createNodeId, | ||
createContentDigest, | ||
resource, | ||
parent, | ||
}) => { | ||
const node = { | ||
id: createNodeId(`RelatedResource-${resource.url}`), | ||
title: resource.title, | ||
url: resource.url, | ||
parent, | ||
children: [], | ||
plugin: 'gatsby-source-swiftype', | ||
internal: { | ||
type: 'RelatedResource', | ||
content: JSON.stringify(resource), | ||
contentDigest: createContentDigest(resource), | ||
}, | ||
}; | ||
|
||
createNode(node); | ||
|
||
return node; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const fs = require('fs'); | ||
const search = require('./search'); | ||
|
||
module.exports = async ({ node, siteUrl }, pluginOptions) => { | ||
const { | ||
refetch, | ||
engineKey, | ||
limit, | ||
file, | ||
getParams = () => ({}), | ||
getPath, | ||
} = pluginOptions; | ||
|
||
const pathname = getPath({ node }); | ||
|
||
if (refetch) { | ||
return search(siteUrl + pathname, getParams({ node }), { | ||
engineKey, | ||
limit, | ||
}); | ||
} | ||
|
||
const data = JSON.parse(fs.readFileSync(file)); | ||
|
||
return data[pathname] || []; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
const fetch = require('node-fetch'); | ||
const { appendTrailingSlash, stripTrailingSlash } = require('./utils/url'); | ||
|
||
const normalizeUrl = (url) => { | ||
const prefix = url.startsWith('!') ? '!' : ''; | ||
const plainUrl = url.replace(/^!/, ''); | ||
|
||
return [ | ||
prefix + appendTrailingSlash(plainUrl), | ||
prefix + stripTrailingSlash(plainUrl), | ||
]; | ||
}; | ||
|
||
const uniq = (arr) => [...new Set(arr)]; | ||
|
||
module.exports = async (url, params = {}, { engineKey, limit }) => { | ||
const { page: pageFilters = {} } = params.filters || {}; | ||
|
||
const res = await fetch( | ||
'https://search-api.swiftype.com/api/v1/public/engines/search.json', | ||
{ | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
...params, | ||
engine_key: engineKey, | ||
per_page: limit, | ||
filters: { | ||
...params.filters, | ||
page: { | ||
...pageFilters, | ||
url: uniq([ | ||
...normalizeUrl(`!${url}`), | ||
...(pageFilters.url || []).flatMap(normalizeUrl), | ||
]), | ||
}, | ||
}, | ||
}), | ||
} | ||
); | ||
|
||
const { records } = await res.json(); | ||
|
||
return records.page; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
const hasQueryParams = (urlString) => { | ||
const url = new URL(urlString); | ||
|
||
return Boolean(url.search); | ||
}; | ||
|
||
exports.appendTrailingSlash = (url) => { | ||
if (hasQueryParams(url)) { | ||
return url; | ||
} | ||
|
||
return url.endsWith('/') ? url : `${url}/`; | ||
}; | ||
|
||
exports.stripTrailingSlash = (url) => { | ||
if (hasQueryParams(url)) { | ||
return url; | ||
} | ||
|
||
return url.endsWith('/') ? url.replace(/\/$/, '') : url; | ||
}; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this for caching reasons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. By default, the data is resolved from the
src/data/related-pages.json
file. When we need to refresh that data and make new requests to Swiftype, setting theBUILD_RELATED_CONTENT
environment variable will instruct the plugin to go make new requests to Swiftype and save them in the JSON file.