Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,93 @@ module.exports = {
'gatsby-plugin-react-helmet',
'gatsby-plugin-sitemap',
'gatsby-transformer-json',
{
resolve: 'gatsby-plugin-feed',
options: {
query: `
{
site {
siteMetadata {
siteTitle
siteDescription
siteUrl
}
}
}
`,
feeds: [
{
serialize: ({
query: { site, allHistoryJson, allMarkdownRemark },
}) => {
// Create a lookup object for rules by file path
const rulesMap = {};
allMarkdownRemark.nodes.forEach((rule) => {
const filePath = `rules/${rule.frontmatter.uri}/rule.md`;
rulesMap[filePath] = rule;
});

// Get recent updates from history, filter out archived rules
return allHistoryJson.edges
.filter((edge) => {
const rule = rulesMap[edge.node.file];
return rule && !rule.frontmatter.archivedreason;
})
.slice(0, 50) // Limit to 50 most recent updates
.map((edge) => {
const rule = rulesMap[edge.node.file];
const url = `${site.siteMetadata.siteUrl}/${rule.frontmatter.uri}`;

return {
title: rule.frontmatter.title,
description:
rule.frontmatter.seoDescription ||
rule.excerpt ||
`Updated by ${edge.node.lastUpdatedBy}`,
date: edge.node.lastUpdated,
url: url,
guid: rule.frontmatter.guid,
custom_elements: [
{ 'dc:creator': edge.node.lastUpdatedBy },
{ pubDate: edge.node.lastUpdated },
],
};
});
},
query: `
{
allHistoryJson(sort: {lastUpdated: DESC}) {
edges {
node {
file
lastUpdated
lastUpdatedBy
}
}
}
allMarkdownRemark(filter: {frontmatter: {type: {eq: "rule"}}}) {
nodes {
excerpt(pruneLength: 250)
frontmatter {
title
uri
archivedreason
seoDescription
}
}
}
}
`,
output: '/rss.xml',
title: 'SSW Rules - Recent Updates',
description: 'Stay updated with the latest changes to SSW Rules',
site_url: 'https://www.ssw.com.au/rules',
feed_url: 'https://www.ssw.com.au/rules/rss.xml',
language: 'en',
},
],
},
},
'gatsby-plugin-postcss',
{
resolve: 'gatsby-source-git',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"gatsby-plugin-breadcrumb": "^12.3.2",
"gatsby-plugin-client-side-redirect": "^1.1.0",
"gatsby-plugin-decap-cms": "^4.0.4",
"gatsby-plugin-feed": "5.13.1",
"gatsby-plugin-fontawesome-css": "^1.2.0",
"gatsby-plugin-google-gtag": "^5.13.1",
"gatsby-plugin-google-tagmanager": "^5.13.1",
Expand Down
114 changes: 114 additions & 0 deletions scripts/validate-rss-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env node
/* eslint-disable no-console */

/**
* This script validates the RSS feed configuration in gatsby-config.js
* It checks that the required configuration is present and properly structured.
*/

const path = require('path');

console.log('🔍 Validating RSS Feed Configuration...\n');

try {
// Load gatsby-config.js
const configPath = path.join(__dirname, '..', 'gatsby-config.js');
const config = require(configPath);

// Find the RSS feed plugin
const feedPlugin = config.plugins.find((plugin) => {
if (typeof plugin === 'object' && plugin.resolve) {
return plugin.resolve === 'gatsby-plugin-feed';
}
return false;
});

if (!feedPlugin) {
console.error('❌ gatsby-plugin-feed not found in gatsby-config.js');
process.exit(1);
}

console.log('✅ gatsby-plugin-feed found in configuration');

// Validate feed options
if (!feedPlugin.options) {
console.error('❌ Feed plugin has no options');
process.exit(1);
}

console.log('✅ Feed plugin has options');

// Validate feeds array
if (!feedPlugin.options.feeds || !Array.isArray(feedPlugin.options.feeds)) {
console.error('❌ Feed plugin has no feeds array');
process.exit(1);
}

console.log('✅ Feed plugin has feeds array');

// Validate first feed
const feed = feedPlugin.options.feeds[0];
if (!feed) {
console.error('❌ No feed defined');
process.exit(1);
}

console.log('✅ Feed is defined');

// Validate feed properties
const requiredProps = ['serialize', 'query', 'output', 'title'];
const missingProps = requiredProps.filter((prop) => !feed[prop]);

if (missingProps.length > 0) {
console.error(
`❌ Feed missing required properties: ${missingProps.join(', ')}`
);
process.exit(1);
}

console.log('✅ Feed has all required properties');

// Validate output path
if (feed.output !== '/rss.xml') {
console.error(`❌ Feed output path is ${feed.output}, expected /rss.xml`);
process.exit(1);
}

console.log('✅ Feed output path is /rss.xml');

// Validate feed metadata
console.log('\nFeed Metadata:');
console.log(` Title: ${feed.title}`);
console.log(` Description: ${feed.description}`);
console.log(` Output: ${feed.output}`);
console.log(` Site URL: ${feed.site_url}`);
console.log(` Feed URL: ${feed.feed_url}`);

// Validate query includes required fields
const requiredQueryFields = [
'allHistoryJson',
'allMarkdownRemark',
'lastUpdated',
'lastUpdatedBy',
];
const queryMissing = requiredQueryFields.filter(
(field) => !feed.query.includes(field)
);

if (queryMissing.length > 0) {
console.error(
`⚠️ Warning: Feed query might be missing fields: ${queryMissing.join(', ')}`
);
} else {
console.log('\n✅ Feed query includes all expected fields');
}

console.log('\n✅ RSS Feed configuration is valid!');
console.log(
'\n💡 The RSS feed will be available at /rss.xml after the site is built.'
);
process.exit(0);
} catch (error) {
console.error('❌ Error validating RSS feed configuration:', error.message);
process.exit(1);
}
52 changes: 52 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6996,6 +6996,7 @@ __metadata:
gatsby-plugin-breadcrumb: "npm:^12.3.2"
gatsby-plugin-client-side-redirect: "npm:^1.1.0"
gatsby-plugin-decap-cms: "npm:^4.0.4"
gatsby-plugin-feed: "npm:5.13.1"
gatsby-plugin-fontawesome-css: "npm:^1.2.0"
gatsby-plugin-google-gtag: "npm:^5.13.1"
gatsby-plugin-google-tagmanager: "npm:^5.13.1"
Expand Down Expand Up @@ -13857,6 +13858,24 @@ __metadata:
languageName: node
linkType: hard

"gatsby-plugin-feed@npm:5.13.1":
version: 5.13.1
resolution: "gatsby-plugin-feed@npm:5.13.1"
dependencies:
"@babel/runtime": "npm:^7.20.13"
common-tags: "npm:^1.8.2"
fs-extra: "npm:^11.1.1"
gatsby-plugin-utils: "npm:^4.13.1"
lodash.merge: "npm:^4.6.2"
rss: "npm:^1.2.2"
peerDependencies:
gatsby: ^5.0.0-next
react: ^18.0.0 || ^0.0.0
react-dom: ^18.0.0 || ^0.0.0
checksum: 35e88d70f26ebf8fc959f0e800ead7ed96ae2c77fc6499cba22656ac8252b073554a02024bb3c858d9f380fb70c70aa20341a9a8d7c13b101c22143e29900366
languageName: node
linkType: hard

"gatsby-plugin-fontawesome-css@npm:^1.2.0":
version: 1.2.0
resolution: "gatsby-plugin-fontawesome-css@npm:1.2.0"
Expand Down Expand Up @@ -18885,6 +18904,22 @@ __metadata:
languageName: node
linkType: hard

"mime-db@npm:~1.25.0":
version: 1.25.0
resolution: "mime-db@npm:1.25.0"
checksum: a90951c80700314d6131e106cbf56ae94718d046e9669a5afd7f91e603248da328aad5b63314865fd9547f4688465ac62d1ace59e1ffdb73688452a28a9c3622
languageName: node
linkType: hard

"mime-types@npm:2.1.13":
version: 2.1.13
resolution: "mime-types@npm:2.1.13"
dependencies:
mime-db: "npm:~1.25.0"
checksum: a53a0453f7863fa2d823025ce92978f5142a18528316caa53cbb1d4212be847973e9a5f2466362cbd2351a512e369252fc2c88c9c5bbc85df4bd8b42214f1785
languageName: node
linkType: hard

"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.30, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34":
version: 2.1.35
resolution: "mime-types@npm:2.1.35"
Expand Down Expand Up @@ -23541,6 +23576,16 @@ __metadata:
languageName: node
linkType: hard

"rss@npm:^1.2.2":
version: 1.2.2
resolution: "rss@npm:1.2.2"
dependencies:
mime-types: "npm:2.1.13"
xml: "npm:1.0.1"
checksum: 7e37a6ed1820b69476c76e4fefe09f69dd7505408e9fc7690441a5190aca2e2e2faf8d19575fd1efd66debfb178893374fbff9abf68e5416f5e4d4cccb7ae8b9
languageName: node
linkType: hard

"run-async@npm:^2.4.0":
version: 2.4.1
resolution: "run-async@npm:2.4.1"
Expand Down Expand Up @@ -27520,6 +27565,13 @@ __metadata:
languageName: node
linkType: hard

"xml@npm:1.0.1":
version: 1.0.1
resolution: "xml@npm:1.0.1"
checksum: 04bcc9b8b5e7b49392072fbd9c6b0f0958bd8e8f8606fee460318e43991349a68cbc5384038d179ff15aef7d222285f69ca0f067f53d071084eb14c7fdb30411
languageName: node
linkType: hard

"xmlbuilder@npm:^15.1.1":
version: 15.1.1
resolution: "xmlbuilder@npm:15.1.1"
Expand Down
Loading