Skip to content

Commit 41ae1c0

Browse files
authoredNov 2, 2020
feat(gatsby): release plugin option validation (#27437)
* chore(gatsby): add @gatsbyVersion pragma to pluginOptionsSchema Node API This will make Gatsby prompt users on old versions of gatsby that don't support the API to upgrade to the new version. * 2.25.0! * Remove GATSBY_EXPERIMENTAL_PLUGIN_OPTION_VALIDATION feature flag * Fix incorrect option in gatsby-admin; * Fix tests * Remove obsolete snapshots * Trigger Build * Remove flag from remark-autolink-headers * Fix gatsby-plugin-mdx default
1 parent a33e7fb commit 41ae1c0

File tree

24 files changed

+505
-744
lines changed

24 files changed

+505
-744
lines changed
 

‎.jestSetup.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
process.env.GATSBY_RECIPES_NO_COLOR = "true"
2-
process.env.GATSBY_EXPERIMENTAL_PLUGIN_OPTION_VALIDATION = "true"

‎packages/gatsby-admin/gatsby-config.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
module.exports = {
22
plugins: [
3-
{
4-
resolve: "gatsby-plugin-react-helmet",
5-
options: {
6-
test: false,
7-
},
8-
},
3+
"gatsby-plugin-react-helmet",
94
{
105
resolve: "gatsby-plugin-webfonts",
116
options: {

‎packages/gatsby-plugin-feed/src/__tests__/__snapshots__/gatsby-node.js.snap

-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,3 @@ exports[`Test plugin feed custom properties work properly 1`] = `"<?xml version=
55
exports[`Test plugin feed custom query runs 1`] = `"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?><rss xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\" version=\\"2.0\\"><channel><title><![CDATA[my feed]]></title><description><![CDATA[a description]]></description><link>http://github.com/dylang/node-rss</link><generator>GatsbyJS</generator><lastBuildDate>Mon, 01 Jan 2018 00:00:00 GMT</lastBuildDate><item><title><![CDATA[No title]]></title><description><![CDATA[post description]]></description><link>http://dummy.url/a-custom-path</link><guid isPermaLink=\\"true\\">http://dummy.url/a-custom-path</guid></item><item><title><![CDATA[No title]]></title><description><![CDATA[post description]]></description><link>http://dummy.url/another-custom-path</link><guid isPermaLink=\\"true\\">http://dummy.url/another-custom-path</guid></item></channel></rss>"`;
66
77
exports[`Test plugin feed default settings work properly 1`] = `"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?><rss xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\" version=\\"2.0\\"><channel><title><![CDATA[a sample title]]></title><description><![CDATA[a description]]></description><link>http://github.com/dylang/node-rss</link><generator>GatsbyJS</generator><lastBuildDate>Mon, 01 Jan 2018 00:00:00 GMT</lastBuildDate><item><title><![CDATA[No title]]></title><description><![CDATA[post description]]></description><link>http://dummy.url/a-slug</link><guid isPermaLink=\\"false\\">http://dummy.url/a-slug</guid><content:encoded></content:encoded></item></channel></rss>"`;
8-
9-
exports[`Test plugin feed options validation throws when invalid plugin options 1`] = `[Error: [Config Validation]: "feeds[0].output" is required]`;
10-
11-
exports[`Test plugin feed options validation throws when invalid plugin options 2`] = `[Error: [Config Validation]: "feeds[0].query" is required]`;

‎packages/gatsby-plugin-feed/src/__tests__/gatsby-node.js

+1-103
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
jest.mock(`fs-extra`)
22
const fs = require(`fs-extra`)
33
const path = require(`path`)
4-
const { onPreBootstrap, onPostBuild } = require(`../gatsby-node`)
4+
const { onPostBuild } = require(`../gatsby-node`)
55
const DATE_TO_USE = new Date(`2018`)
66
const _Date = Date
77
global.Date = jest.fn(() => DATE_TO_USE)
@@ -15,108 +15,6 @@ describe(`Test plugin feed`, () => {
1515
fs.mkdirp = jest.fn().mockResolvedValue()
1616
})
1717

18-
describe(`options validation`, () => {
19-
const setup = async options => {
20-
const reporter = {
21-
stripIndent: jest.fn(value => value.trim()),
22-
warn: jest.fn(),
23-
}
24-
await onPreBootstrap({ reporter }, options)
25-
26-
return [reporter, options]
27-
}
28-
29-
const deprecationNotice = `This behavior will be removed in the next major release of gatsby-plugin-feed`
30-
31-
it(`removes plugins`, async () => {
32-
const options = { plugins: [] }
33-
34-
await setup(options)
35-
36-
expect(options.plugins).toBeUndefined()
37-
})
38-
39-
it(`warns when feeds is not supplied`, async () => {
40-
const options = {}
41-
42-
const [reporter] = await setup(options)
43-
44-
expect(reporter.warn).toHaveBeenCalledTimes(1)
45-
expect(reporter.warn).toHaveBeenCalledWith(
46-
expect.stringContaining(deprecationNotice)
47-
)
48-
})
49-
50-
it(`warns when individual feed does not have title`, async () => {
51-
const options = {
52-
feeds: [
53-
{
54-
output: `rss.xml`,
55-
query: `{}`,
56-
serialize: () => {},
57-
},
58-
],
59-
}
60-
61-
const [reporter] = await setup(options)
62-
63-
expect(reporter.warn).toHaveBeenCalledTimes(1)
64-
expect(reporter.warn).toHaveBeenCalledWith(
65-
expect.stringContaining(`title`)
66-
)
67-
})
68-
69-
it(`warns when individual feed does not have serialize function`, async () => {
70-
const options = {
71-
feeds: [
72-
{
73-
output: `rss.xml`,
74-
query: `{}`,
75-
title: `my feed`,
76-
},
77-
],
78-
}
79-
80-
const [reporter] = await setup(options)
81-
82-
expect(reporter.warn).toHaveBeenCalledTimes(1)
83-
expect(reporter.warn).toHaveBeenCalledWith(
84-
expect.stringContaining(deprecationNotice)
85-
)
86-
})
87-
88-
it(`throws when invalid plugin options`, async () => {
89-
const invalidOptions = [
90-
{
91-
feeds: [
92-
{
93-
// output is missing
94-
query: `{}`,
95-
},
96-
],
97-
},
98-
{
99-
feeds: [
100-
{
101-
output: `rss.xml`,
102-
// query is missing
103-
},
104-
],
105-
},
106-
]
107-
108-
for (let options of invalidOptions) {
109-
try {
110-
await setup(options)
111-
} catch (e) {
112-
expect(e).toMatchSnapshot()
113-
}
114-
}
115-
116-
expect.assertions(invalidOptions.length)
117-
})
118-
})
119-
12018
it(`default settings work properly`, async () => {
12119
fs.writeFile = jest.fn()
12220
fs.writeFile.mockResolvedValue(true)

‎packages/gatsby-plugin-feed/src/gatsby-node.js

+1-60
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,13 @@ import fs from "fs-extra"
22
import path from "path"
33
import RSS from "rss"
44
import merge from "lodash.merge"
5-
import { Joi } from "gatsby-plugin-utils"
65

76
import { defaultOptions, runQuery } from "./internals"
87
import pluginOptionsSchema from "./plugin-options"
98

109
const publicPath = `./public`
1110

12-
const warnMessage = (error, behavior) => `
13-
gatsby-plugin-feed was initialized in gatsby-config.js without a ${error}.
14-
This means that the plugin will use ${behavior}, which may not match your use case.
15-
This behavior will be removed in the next major release of gatsby-plugin-feed.
16-
For more info, check out: https://gatsby.dev/adding-rss-feed
17-
`
18-
19-
if (process.env.GATSBY_EXPERIMENTAL_PLUGIN_OPTION_VALIDATION) {
20-
exports.pluginOptionsSchema = pluginOptionsSchema
21-
}
11+
exports.pluginOptionsSchema = pluginOptionsSchema
2212

2313
// TODO: remove in the next major release
2414
// A default function to transform query data into feed entries.
@@ -33,55 +23,6 @@ const serialize = ({ query: { site, allMarkdownRemark } }) =>
3323
}
3424
})
3525

36-
exports.onPreBootstrap = async function onPreBootstrap(
37-
{ reporter },
38-
pluginOptions
39-
) {
40-
delete pluginOptions.plugins
41-
42-
try {
43-
// TODO: remove this once pluginOptionsSchema is stable
44-
const { value: normalized, error } = await pluginOptionsSchema({
45-
Joi,
46-
}).validate(pluginOptions, {
47-
externals: false,
48-
})
49-
50-
if (error) throw error
51-
52-
if (!normalized.feeds) {
53-
reporter.warn(
54-
reporter.stripIndent(
55-
warnMessage(`feeds option`, `the internal RSS feed creation`)
56-
)
57-
)
58-
} else if (normalized.feeds.some(feed => typeof feed.title !== `string`)) {
59-
reporter.warn(
60-
reporter.stripIndent(
61-
warnMessage(`title in a feed`, `the default feed title`)
62-
)
63-
)
64-
} else if (
65-
normalized.feeds.some(feed => typeof feed.serialize !== `function`)
66-
) {
67-
reporter.warn(
68-
reporter.stripIndent(
69-
warnMessage(
70-
`serialize function in a feed`,
71-
`the internal serialize function`
72-
)
73-
)
74-
)
75-
}
76-
} catch (e) {
77-
throw new Error(
78-
e.details
79-
.map(detail => `[Config Validation]: ${detail.message}`)
80-
.join(`\n`)
81-
)
82-
}
83-
}
84-
8526
exports.onPostBuild = async ({ graphql }, pluginOptions) => {
8627
/*
8728
* Run the site settings query to gather context, then
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,38 @@
1-
if (process.env.GATSBY_EXPERIMENTAL_PLUGIN_OPTION_VALIDATION) {
2-
exports.pluginOptionsSchema = ({ Joi }) =>
3-
// TODO: make sure that trackingId gets required() when releasing a major version
4-
Joi.object({
5-
trackingId: Joi.string().description(
6-
`The property ID; the tracking code won't be generated without it`
1+
exports.pluginOptionsSchema = ({ Joi }) =>
2+
// TODO: make sure that trackingId gets required() when releasing a major version
3+
Joi.object({
4+
trackingId: Joi.string().description(
5+
`The property ID; the tracking code won't be generated without it`
6+
),
7+
head: Joi.boolean()
8+
.default(false)
9+
.description(
10+
`Defines where to place the tracking script - \`true\` in the head and \`false\` in the body`
711
),
8-
head: Joi.boolean()
9-
.default(false)
10-
.description(
11-
`Defines where to place the tracking script - \`true\` in the head and \`false\` in the body`
12-
),
13-
anonymize: Joi.boolean().default(false),
14-
respectDNT: Joi.boolean().default(false),
15-
exclude: Joi.array()
16-
.items(Joi.string())
17-
.default([])
18-
.description(`Avoids sending pageview hits from custom paths`),
19-
pageTransitionDelay: Joi.number()
20-
.default(0)
21-
.description(
22-
`Delays sending pageview hits on route update (in milliseconds)`
23-
),
24-
optimizeId: Joi.string().description(
25-
`Enables Google Optimize using your container Id`
12+
anonymize: Joi.boolean().default(false),
13+
respectDNT: Joi.boolean().default(false),
14+
exclude: Joi.array()
15+
.items(Joi.string())
16+
.default([])
17+
.description(`Avoids sending pageview hits from custom paths`),
18+
pageTransitionDelay: Joi.number()
19+
.default(0)
20+
.description(
21+
`Delays sending pageview hits on route update (in milliseconds)`
2622
),
27-
experimentId: Joi.string().description(
28-
`Enables Google Optimize Experiment ID`
29-
),
30-
variationId: Joi.string().description(
31-
`Set Variation ID. 0 for original 1,2,3....`
32-
),
33-
defer: Joi.boolean().description(
34-
`Defers execution of google analytics script after page load`
35-
),
36-
sampleRate: Joi.number(),
37-
siteSpeedSampleRate: Joi.number(),
38-
cookieDomain: Joi.string(),
39-
})
40-
} else {
41-
exports.onPreInit = ({ reporter }, { trackingId } = {}) => {
42-
if (!trackingId) {
43-
reporter.warn(
44-
`The Google Analytics plugin requires a tracking ID. Did you mean to add it?`
45-
)
46-
}
47-
}
48-
}
23+
optimizeId: Joi.string().description(
24+
`Enables Google Optimize using your container Id`
25+
),
26+
experimentId: Joi.string().description(
27+
`Enables Google Optimize Experiment ID`
28+
),
29+
variationId: Joi.string().description(
30+
`Set Variation ID. 0 for original 1,2,3....`
31+
),
32+
defer: Joi.boolean().description(
33+
`Defers execution of google analytics script after page load`
34+
),
35+
sampleRate: Joi.number(),
36+
siteSpeedSampleRate: Joi.number(),
37+
cookieDomain: Joi.string(),
38+
})

‎packages/gatsby-plugin-google-tagmanager/src/gatsby-node.js

+25-27
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,31 @@ exports.onPreInit = (args, options) => {
1212
}
1313
}
1414

15-
if (process.env.GATSBY_EXPERIMENTAL_PLUGIN_OPTION_VALIDATION) {
16-
exports.pluginOptionsSchema = ({ Joi }) =>
17-
Joi.object({
18-
id: Joi.string().description(
19-
`Google Tag Manager ID that can be found in your Tag Manager dashboard.`
15+
exports.pluginOptionsSchema = ({ Joi }) =>
16+
Joi.object({
17+
id: Joi.string().description(
18+
`Google Tag Manager ID that can be found in your Tag Manager dashboard.`
19+
),
20+
includeInDevelopment: Joi.boolean()
21+
.default(false)
22+
.description(
23+
`Include Google Tag Manager when running in development mode.`
2024
),
21-
includeInDevelopment: Joi.boolean()
22-
.default(false)
23-
.description(
24-
`Include Google Tag Manager when running in development mode.`
25-
),
26-
defaultDataLayer: Joi.object()
27-
.default(null)
28-
.description(
29-
`Data layer to be set before Google Tag Manager is loaded. Should be an object or a function.`
30-
),
31-
gtmAuth: Joi.string().description(
32-
`Google Tag Manager environment auth string.`
25+
defaultDataLayer: Joi.object()
26+
.default(null)
27+
.description(
28+
`Data layer to be set before Google Tag Manager is loaded. Should be an object or a function.`
3329
),
34-
gtmPreview: Joi.string().description(
35-
`Google Tag Manager environment preview name.`
30+
gtmAuth: Joi.string().description(
31+
`Google Tag Manager environment auth string.`
32+
),
33+
gtmPreview: Joi.string().description(
34+
`Google Tag Manager environment preview name.`
35+
),
36+
dataLayerName: Joi.string().description(`Data layer name.`),
37+
routeChangeEventName: Joi.string()
38+
.default(`gatsby-route-change`)
39+
.description(
40+
`Name of the event that is triggered on every Gatsby route change.`
3641
),
37-
dataLayerName: Joi.string().description(`Data layer name.`),
38-
routeChangeEventName: Joi.string()
39-
.default(`gatsby-route-change`)
40-
.description(
41-
`Name of the event that is triggered on every Gatsby route change.`
42-
),
43-
})
44-
}
42+
})

0 commit comments

Comments
 (0)
Please sign in to comment.